1. 程式人生 > >git從安裝到應用的學習

git從安裝到應用的學習

穩定 同名 寫法 .org touch 嘗試 follow 配置 下載安裝

本文內容是對廖雪峰老師Git教程做的筆記,外加一些自己的學習心得,還抱著學以致用的心態來實踐一番

Git學習筆記

分布式版本控制與集中式版本控制的最大區別

集中式的版本控制,本地沒有歷史記錄,完整的倉庫只存在服務器上,如果服務器掛了,就全都掛了,而分布式如果github掛了可以重建一個服務器,然後把任何一個人的倉庫clone過去 一句話總結:分布式版本控制的每個節點都是完整倉庫

  • Git官網直接下載安裝程序 (網速慢的同學請移步國內鏡像)
  • Git User Manual
  • Git中文手冊
$ git --help     //不知道怎麽辦就看幫助唄

Git簡介

安裝Git

下載並安裝Git,安裝完成後,還需要最後一步設置
Git Bash

命令行輸入:

$ git config --global user.name "Your Name"
$ git config --global user.email "[email protected]"

註意git config命令的--global參數,用了這個參數,表示你這臺機器上所有的Git倉庫都會使用這個配置,當然也可以對某個倉庫指定不同的用戶名和Email地址

創建版本庫repository

  • 首先建一個空目錄
$ mkdir learngit //當前目錄下創建文件夾名為learngit
$ cd learngit //進入learngit文件夾目錄下
$ pwd  //顯示當前目錄

pwd命令用於顯示當前目錄

  • 然後通過git init命令把這個目錄變成Git可以管理的倉庫
$ git init  //初始化
$ ls -ah //顯示.git目錄

ls -ah用於顯示.git目錄

把文件添加到版本庫

編寫一個readme.txt,放在learngit目錄下(或者子目錄)

$ vi readme.txt
Vim快捷鍵說明
Esc 退出編輯,跳到命令模式
:w 保存文件但不退出vi
:w file 將修改另外保存到file中,不退出vi
:w! 強制保存,不退出vi
:wq 保存文件並退出vi
:q 不保存文件,退出vi
:q! 不保存文件,強制退出vi
:e! 放棄所有修改,從上次保存文件開始再編輯

1.把文件添加到暫存區

使用git add file_namegit stage file_name

$ git add readme.txt

2.把文件提交到版本庫

$ git commit -m "wrote a readme file"  

-m後面是本次提交的說明,一次可以提交多個文件
註意:git commit 指定文件的時候會直接提交工作區的文件,不指定文件的時候提交的是緩存區stage的所有文件

$ git commit readme.txt -m "balabala"

Git bash操作文件及文件夾命令

命令示例用途
cd d:\Github 切換d盤下面的Github目錄
cd .. 回退到上一個目錄
cd 回退到主目錄
pwd 顯示當前目錄路徑
ls(ll) 列出當前目錄中的所有文件,ll更詳細
ls(ll) -a 列出當前目錄中的所有文件包括隱藏目錄
touch readme.md 新建一個文件
rm readme.md 刪除一個文件
mkdir img 新建一個文件夾img
rm -r img 刪除一個文件夾img
mv readme.md img 把當前目錄下的目標文件移動到一個指定目錄,使用相對路徑
reset 清屏,清空git bash 命令窗口中的所有內容

查看Git安裝目錄

  • Windows
    • cmd where git
  • Mac
    • 命令行 which git

時光穿梭機

版本退回

git reset --hard commit_id
  • HEAD指向的版本就是當前版本,因此,Git允許我們在版本的歷史之間穿梭,使用命令git reset --hard commit_id
    • Git的commit_d(版本號)是一個十六進制的用SHA1計算出來的數字
    • 在Git中用HEAD表示當前版本,上一個版本就是HEAD^,上一百個版本寫成HEAD~100
    • 使用git reset --hard HEAD^命令退回上一個版本
  • 穿梭前,用git log可以查看提交歷史,以便確定要回退到哪個版本
    • 使用git log --pretty=oneline讓記錄單行顯示
    • 使用git loggit reflogfile_name查看指定文件的歷史
  • 要重返未來,用git reflog查看命令歷史,以便確定要回到未來的哪個版本
    • Git 提供一個命令git reflog來記錄你的每一次命令,這樣就可以找到所有版本的commit id

工作區和暫存區

  • 工作區(Working Directory)
    你在電腦裏能看到的目錄
  • 版本庫(Repository)
    工作區有一個隱藏目錄.git,這個不算工作區,而是Git的版本庫.我們可以稱它為Repo
    Repo裏存放了很多東西,其中最重要的就是暫存區stage(或者叫index),還有Git為我們自動創建的第一個分支(Branch)master.以及指向master的一個指針叫HEAD.
    技術分享圖片
    cat file_name命令,其功能是顯示在工作區、暫存區和分支裏同名文檔的最新修改版本的內容

前面講了我們把文件往Git版本庫裏添加的時候,是分兩步執行的:
第一步是用git add把文件添加進去,實際上就是把文件修改添加到暫存區;
第二步是用git commit提交更改,實際上就是把暫存區的所有內容提交到當前分支。

掌握倉庫當前的狀態

$ git status

查看修改內容

下面是關於 git diff的一些使用區別
技術分享圖片
另外可以使用git diff commit_id_1 commit_id_2比較兩個不同版本的區別

cat file_name命令,其功能是顯示在工作區、暫存區和分支裏同名文檔的最新修改版本的內容

撤銷修改

  • 場景1:當你改亂了工作區某個文件的內容,想直接丟棄工作區的修改時,用命令git checkout -- file_name
    • 可以用git checkout -- *丟棄所有工作區文件的修改
  • 場景2:當你不但改亂了工作區某個文件的內容,還添加到了暫存區時,想丟棄修改,分兩步
    • 第一步用命令git reset HEAD file_name就回到了場景1
      • 使用git reset HEAD丟棄所有暫存區的修改
    • 第二步按場景1操作
  • 場景3:已經提交了不合適的修改到版本庫時,想要撤銷本次提交,參考版本回退一節,不過前提是沒有推送到遠程庫。

註意:使用版本退回操作git reset --hard 會導致所有暫存區和工作區的當前修改但未commit的內容全部丟棄. 特別:使用git reset --hard HEAD會導致上述結果,並在git reflog中生成記錄,但不改變

文件名裏有空格和()的情況

Git命令(或者所有的shell命令中)中出現括“()”時系統把它看做一個有特殊意義的命令從而嘗試去執行它。
因此如果文件名中出現括號,系統找不到括號裏要執行的命令就會報錯。
我們要讓系統忽略括號的特殊意義,方法是用“”雙引號把文件名括起來,或者用轉義符將括號轉義.
例如文件名為git (1).md
以下的寫法都是可以的:
git add "git (1).md" git add git" "\(1\).md git add git" (1)".md

刪除文件

使用rm file_name刪除本地文件
使用 git rm file_name提交刪除到暫存區
使用git commit -m "balabala"提交到本地庫
註意: 可以直接使用git rm file_name刪除本地文件以及提交刪除到暫存區,但僅用於暫存區有此本地文件的情況

遠程倉庫

註冊GitHub賬號

由於你的本地Git倉庫和GitHub倉庫之間的傳輸是通過SSH加密的,所以,需要一點設置:

  • 第1步:創建SSH Key
$ ssh-keygen -t rsa -C  "[email protected]"

然後在用戶主目錄裏找到.ssh目錄,裏面有id_rsaid_rsa.pub兩個文件id_rsa是私鑰,id_rsa.pub是公鑰.

cd ~進入用戶主目錄 cd .ssh進入.ssh目錄 ls列出.ssh目錄的文件 cat ~/.ssh/id_rsa.pub看到id_rsa.pub文件的內容

  • 第2步:登陸GitHub

打開“Account settings”,“SSH Keys”頁面:然後,點“Add SSH Key”,填上任意Title,在Key文本框裏粘貼id_rsa.pub文件的內容

添加遠程庫

  • 要關聯一個遠程庫,使用命令
git remote add origin git@server_name:path/repo_name.git

這裏使用的命令是 git remote add origin [email protected]:HuChanghong/learngit.git

  • 關聯後,使用命令git push -u origin master第一次推送master分支的所有內容

  • 此後,每次本地提交後,只要有必要,就可以使用命令git push origin master推送最新修改

ssh不行是因為你沒有設置ssh秘鑰
1:生成秘鑰:ssh-keygen -t rsa -C "你自己的郵箱"
(這裏不要設置密碼,直接按回車就可以,以後更新就不需要密碼)
2: id_rsa 這個文件是你的私鑰、id_rsa.pub是你的公共密鑰,用記事本打開文件id_rsa.pub,把裏面的內容復制到github配置ssh
3:添加私秘鑰到ssh: ssh-add id_rsa(如果添加失敗可以先執行命令ssh-agent bash,然後再次添加私秘鑰。)
4: 用ssh -T [email protected] 判斷是否綁定成功。如果返回successfully 表示成功

從遠程庫克隆

  • 要克隆一個倉庫,首先必須知道倉庫的地址,然後使用git clone命令克隆。
git clone [email protected]:HuChanghong/MarkdownStudy.git
  • Git支持多種協議,包括https,但通過ssh支持的原生git協議速度最快。

取消鏈接並刪除本地庫

  • 查看本地庫關聯了那些遠程庫git remote -v
  • 取消本地目錄下關聯的遠程庫git remote rm origin
    • 此處origin是指你創建與遠程庫的鏈接的時候所使用的名字
  • 刪除本地庫
    • git branch #顯示本地所有分支
    • git init 1#初始化倉庫
    • ls -a 2#查看內部文件
    • rm -rf .git 3#強刪.git
    • cd .. 5#回退
    • rm -rf file_name 6# 強刪文件夾

分支管理

創建與合並分支

  • 查看分支:git branch
  • 創建分支:git branch <name>
  • 切換分支:git checkout <name>
  • 創建+切換分支:git checkout -b <name>
  • 合並某分支到當前分支:git merge <name>
  • 刪除分支:git branch -d <name>

解決沖突

  • 當Git無法自動合並分支時,就必須首先解決沖突。
  • 解決沖突後,再提交,合並完成。
  • 解決沖突就是把Git合並失敗的文件手動編輯為我們希望的內容,再提交。
  • 用git log --graph命令可以看到分支合並圖。

git merge branch_name提示 conflict
git status查看沖突的文件
打開這個文件,修改保存
用帶參數的git log也可以看到分支的合並情況:
git log --graph --pretty=oneline --abbrev-commit
最後刪除不需要的分支

分支管理策略

在實際開發中,我們應該按照幾個基本原則進行分支管理:首先,master分支應該是非常穩定的,也就是僅用來發布新版本,平時不能在上面幹活;那在哪幹活呢?幹活都在dev分支上,也就是說,dev分支是不穩定的,到某個時候,比如1.0版本發布時,再把dev分支合並到master上,在master分支發布1.0版本;你和你的小夥伴們每個人都在dev分支上幹活,每個人都有自己的分支,時不時地往dev分支上合並就可以了。

合並分支時,加上--no-ff參數就可以用普通模式合並,合並後的歷史有分支,能看出來曾經做過合並,而fast forward合並就看不出來曾經做過合並。

註意--no-ff參數,表示禁用Fast forward 因為本次合並要創建一個新的commit,所以加上-m參數,把commit描述寫進去

git merge --no-ff -m "balabala" branch_name

Bug分支

修復bug時,我們會通過創建新的bug分支進行修復,然後合並,最後刪除; 當手頭工作沒有完成時,先把工作現場git stash一下,然後去修復bug,修復後,再git stash pop,回到工作現場。

Git提供了一個stash功能,可以把當前工作現場“儲藏”起來,等以後恢復現場後繼續工作

git stash

我理解的stash,就像是把當前的WIP壓棧(這裏WIP的含義就是所有修改了但未commit的數據)然後再一個一個取出來,默認的git stash pop是按照自棧頂開始的順序依次出棧,也可以使用git stash pop stash@{num}的方式取出指定的WIP 我們可以用git stash list查看當前壓棧了多少個WIP

註意:git stash不能將未被追蹤的文件(untracked file)壓棧,也就是從未被git add過的文件,也就是你在使用git status命令看到的提示Untracked files所列出的文件,所以在git stash之前一定要用git status確認沒有Untracked files 另外在有WIP沒有commit 或者stash的情況下是無法切換分支的

Feature分支

  • 開發一個新feature,最好新建一個分支;
  • 如果要丟棄一個沒有被合並過的分支,可以通過git branch -D <name>強行刪除

多人協作

多人協作的工作模式通常是這樣:

  • 首先,可以試圖用git push origin <branch-name>推送自己的修改;
  • 如果推送失敗,則因為遠程分支比你的本地更新,需要先用git pull試圖合並;
  • 如果合並有沖突,則解決沖突,並在本地提交;
  • 沒有沖突或者解決掉沖突後,再用git push origin <branch-name>推送就能成功!
  • 如果git pull提示no tracking information,則說明本地分支和遠程分支的鏈接關系沒有創建,用命令git branch --set-upstream-to=origin/<branch-name> <branch-name>
  • 這就是多人協作的工作模式,一旦熟悉了,就非常簡單。
  • 查看遠程庫信息,使用git remote -v
  • 本地新建的分支如果不推送到遠程,對其他人就是不可見的;
  • 從本地推送分支,使用git push origin branch-name,如果推送失敗,先用git pull抓取遠程的新提交;
  • 在本地創建和遠程分支對應的分支,使用git checkout -b branch-name origin/branch-name,本地和遠程分支的名稱最好一致;
  • 建立本地分支和遠程分支的關聯,使用git branch --set-upstream-to=origin/branch-name branch-name
  • 從遠程抓取分支,使用git pull,如果有沖突,要先處理沖突。

rebase

這是git文檔強調的使用註意情形和原則

只對尚未推送或分享給別人的本地修改執行rebase操作清理歷史; 從不對已推送至別處的提交執行rebase操作

gitbook.liuhui998下圖來自這篇鏈接
技術分享圖片
技術分享圖片

git rebase會把你的my work分支裏的每個提交commit取消掉,並且把它們臨時 保存為補丁patch(這些補丁放到".git/rebase"目錄中),然後把mywork分支更新 到最新的origin分支,最後把保存的這些補丁應用到mywork分支上。

mywork分支更新之後,它會指向這些新創建的提交commit,而那些老的提交會被丟棄。 如果運行垃圾收集命令pruning garbage collection, 這些被丟棄的提交就會刪除.

標簽管理

發布一個版本時,我們通常先在版本庫中打一個標簽(tag),這樣,就唯一確定了打標簽時刻的版本。將來無論什麽時候,取某個標簽的版本,就是把那個打標簽的時刻的歷史版本取出來。所以,標簽也是版本庫的一個快照。Git的標簽雖然是版本庫的快照,但其實它就是指向某個commit的指針(跟分支很像對不對?但是分支可以移動,標簽不能移動),所以,創建和刪除標簽都是瞬間完成的。

類似IP和域名的關系

創建標簽

  • 命令git tag <tagname>用於新建一個標簽,默認為HEAD,也可以指定一個commit id
    • git tag tag_name commit_id
  • 命令git tag -a <tagname> -m "blablabla..."可以指定標簽信息;
    • -a指定標簽名,-m指定說明文字
  • 命令git tag可以查看所有標簽。
    • git show tag_name查看標簽信息

操作標簽

命令git push origin <tagname>可以推送一個本地標簽; 命令git push origin --tags可以推送全部未推送過的本地標簽; 命令git tag -d <tagname>可以刪除一個本地標簽; 命令git push origin :refs/tags/<tagname>可以刪除一個遠程標簽。

關聯多個遠程庫

使用多個遠程庫時,我們要註意,git給遠程庫起的默認名稱是origin,如果有多個遠程庫,我們需要用不同的名稱來標識不同的遠程庫。

先用git remote -v查看遠程庫信息

如果本地庫已經關聯了origin的遠程庫,並且,該遠程庫指向GitHub。我們可以刪除已有的GitHub遠程庫

git remote rm origin

使用如下命令關聯遠程庫

git remote add remote_name git@server_name:path/repo_name.git

例如要關聯Github遠程庫

git remote add github [email protected]:Github_id/repo_name.git

再比如要關聯碼雲遠程庫

git remote add gitee [email protected]:Github_id/repo_name.git

此時要推送到不同的遠程庫則代碼中使用對應的遠程庫名稱(remote_name)

git push remote_name master

自定義Git

忽略特殊文件

有些時候,你必須把某些文件放到Git工作目錄中,但又不能提交它們,比如保存了數據庫密碼的配置文件啦,等等,每次git status都會顯示Untracked files ...,有強迫癥的童鞋心裏肯定不爽。好在Git考慮到了大家的感受,這個問題解決起來也很簡單,在Git工作區的根目錄下創建一個特殊的.gitignore文件,然後把要忽略的文件名填進去,Git就會自動忽略這些文件。不需要從頭寫.gitignore文件,GitHub已經為我們準備了各種配置文件,只需要組合一下就可以使用了。所有配置文件可以直接在線瀏覽:https://github.com/github/gitignore

忽略文件的原則是:

  1. 忽略操作系統自動生成的文件,比如縮略圖等;
  2. 忽略編譯生成的中間文件、可執行文件等,也就是如果一個文件是通過另一個文件自動生成的,那自動生成的文件就沒必要放進版本庫,比如Java編譯產生的.class文件;
  3. 忽略你自己的帶有敏感信息的配置文件,比如存放口令的配置文件。

可以用git add -f強制添加被gitignore的文件 可以用git check-ignore命令檢查是什麽規則導致的無法添加文件

git check-ignore -v file_name

註意:.gitignore文件本身要放到版本庫裏,並且可以對.gitignore做版本管理!

Windows下創建.gitignore文件的常用方法

  1. git bashcd切換到根目錄touch .gitignore命令創建
  2. 在資源管理器創建文件時,文件命名“.gitignore.”,註意結尾有個.號,回車確認時系統會自動存成.gitignore
  3. 打開文本編輯器,保存時文件名輸入“.gitignore”,保存類型選“所有文件
  4. 進入cmd命令行,執行 echo > .gitignore 輸入空內容並創建文件,或執行 rename somefile .gitignorecopy somefile .gitignore 從已有文件復制、重命名。

配置別名

只需要先如此如此

git config --global alias.lg "log --color --graph --pretty=format:‘%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset‘ --abbrev-commit"

然後就可以只用git lg輸出辣麽一長串的代碼,看到這裏我沈默了,然後我想了半天,我為什麽幹脆不用GitDesktop呢,可能就是因為熱愛敲代碼吧(霧

配置Git的時候,加上--global是針對當前用戶起作用的,如果不加,那只針對當前的倉庫起作用。 每個倉庫的Git配置文件都放在.git/config文件,打開配置文件,別名就在[alias]後面,要刪除別名,直接把對應的行刪掉即可 當前用戶的Git配置文件放在用戶主目錄下的一個隱藏文件.gitconfig

查看用戶的配置信息使用git config --global --list命令 查看當前倉庫的配置信息使用git config --local --list命令

刪除別名

命令刪除一個已定義的別名 git config --global --unset alias.ci cd .git vi config打開對應的配置文件,別名就在[alias]後面,直接把對應的行刪掉即可

gitconfig配置文件的讀取順序: linux中類似用戶的配置文件一樣有3層,系統級,用戶級,項目級。 windows也基本一樣,但常常只存在於是用戶根目錄(C:\User\xxx),項目目錄中。 最下層的覆蓋上面的,alias配置也在其中,手動改配置文件也和命令一樣。 加了--global選項的,表示配置寫到了用戶級,--system是系統級,win是在安裝目錄(如C:\Program Files\Git\mingw64\etc),不加就在項目級

來自:https://github.com/HuChanghong/learngit

git從安裝到應用的學習