Git 的使用大全

Git 的基礎配置

1. user.name && user.email 配置

配置使用 Git 倉庫的用戶 name 和 email,可設置全局的 user.nameuser.email,在命令行輸入:node

$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"

注意 git config 命令的 --global 參數,表示這臺機器上全部的 Git 倉庫都會使用這個配置,若是不想使用全局的信息,想對某個倉庫指定不一樣的用戶名和 Email 地址,可在當前項目下設置:git

$ git config user.name "Your Name"
$ git config user.email "email@example.com"

2. 配置別名

$ git config --global alias.st status   # 用 st 代替 status
$ git config --global alias.cm commit   # 用 cm 代替 commit

3. 查看配置

可經過如下命令查看當前項目的用戶名和郵箱。github

$ git config user.name
$ git config user.email

經過如下命令查看配置列表:shell

$ git config --list           # 默認全局配置列表
$ git config --local --list   # 當前文件的配置列表

4. .gitignore 文件

.gitignore 中列出來的文件或文件目錄,在提交到版本庫的時候會忽略,且不會記錄其中的修改記錄。babel

  • 每一行表明一條規則。不帶任何符號的文件名,表明全部路徑的該文件都會被忽略。
  • # 開始的行,被視爲註釋。若是規則是以 # 開頭,則可用 \ 反斜槓轉譯。
  • 斜槓 / 用做目錄分隔符。若是尾部有 /,則只匹配文件夾,若是尾部沒有 /,則便可匹配文件,也可匹配文件夾。若是頭部或中間有 /,則表示基於 .gitignore 文件所在位置的相對路徑,如 a/b 不會匹配 c/a/b
  • * 號可表明除了 / 以外的任何字符;? 號匹配除了 / 以外的任何 一個 字符。
  • **/ 號表示匹配全部目錄,如 **/node_modules 表示任何目錄下的 node_modules 文件或者文件夾,效果同 node_modules
  • /** 表示目錄內無限深度的任何文件。如 abc/** 匹配 abc 目錄下的全部文件。
  • /**/ 表示零個或多個目錄。如 a/**/b 匹配 a/ba/x/ba/x/y/b 等等。
# 註釋
node_modules
dist
...

建立版本庫

建立新的本地版本庫

$ mkdir learngit  # make directory 新建文件夾
$ cd learngit     # 進入文件夾
$ git init        # 初始化倉庫

初始化後文件夾裏會多一個 .git 的隱藏文件夾,可經過命令 ls -ah 查看。app

克隆遠程版本庫

$ git clone URL                #  clone 遠程項目
$ git clone -b <遠程分支> URL   #  clone 指定分支
$ git clone URL <文件夾名>      #  clone 遠程項目到本地該文件目錄下(會新建文件夾)

git clone URL 會克隆所有分支,但只能看到 master 分支,須要建立本地分支並關聯到遠程 origin 的對應分支,才能看到對應的分支。編輯器

項目文件有更改,需及時更新本地版本庫

遠程文件有改變 git pull

拉取最新項目文件,git pull == git fetch + git merge學習

$ git pull   # git pull = git fetch + git merge
$ git pull origin <分支名>   # 拉取遠程某分支代碼

若是是團隊合做開發,在每次修改本地文件以前,需 pull 一下最新代碼,儘可能減小衝突。若是 pull 的時候,提示有衝突,可以使用如下方法解決:fetch

  • 先將本地更改 stash 存儲起來,而後 pull,解決衝突,以後再 addcommitpullpush
  • addcommitpull 下來解決衝突,完了後再 addcommitpullpush

若是使用第二種方法解決衝突,會形成提交樹分叉較多,不利於查看提交記錄,所以可使用 rebase 的方式 pull 代碼。動畫

$ git pull --rebase  # = git fetch + git rebase
# 解決衝突
$ git add
$ git rebase --continue
$ git push

本地文件有改變

1. 查看文件的改變狀況:

先用 git status 查看當前工做區的狀態(有變化的文件):

$ git status      # 詳細輸出更改狀態
$ git status -s   # 簡短輸出更改狀態

若是顯示文件被修改過,可用 git diff 查看修改內容:

$ git diff           # 是工做區(work dict)和暫存區(stage)的比較
$ git diff --cached  # 是暫存區(stage)和分支(master)的比較
$ git diff HEAD      # 查看工做區和版本庫裏面最新版本的區別,HEAD能夠換成任何版本號(commit id)

2. 用 git add 將文件添加到暫存區(staging area):

$ git add README.md
$ git add .        # 所有有更改的文件

git add 後可寫文件名,可寫文件夾,可寫點 git add . 表示所有更改。

3. 用 git checkout -- <file> 丟棄工做區的修改

命令 git checkout -- README.md 意思就是,把README.md 文件在工做區的修改所有撤銷,這裏有兩種狀況:

  • 一種是 README.md 自修改後尚未被放到暫存區,如今,撤銷修改就回到和版本庫如出一轍的狀態;
  • 一種是 README.md 已經添加到暫存區後,又做了修改,如今,撤銷修改就回到添加到暫存區後的狀態。

總之,就是讓這個文件回到最近一次 git commitgit add 時的狀態。

4. 用 git reset HEAD <filename> 撤銷暫存區的修改,從新放回工做區。

若是不加文件名則表示撤銷上次 add 的所有文件

git reset HEAD <filename>  # 取消暫存區的文件

5. 最新版本中使用 git restore 代替了 resetcheckout

git restore <file>            # 丟棄工做區的更改
git restore --staged <file>   # 撤銷暫存區 add 的文件,從新放回工做區。

6. 用git commit將文件提交到本地倉庫:

$ git commit -m "wrote a readme file"
$ git commit -am '修改文件'  # git add + git commit

將暫存區的更改提交到本地倉庫,只有本機可見。-m 後面輸入的是本次提交的說明,方便記錄每次提交的改動,所以最好是有意義的說明。

7. commit 後的版本回退

1. 先查看提交日誌

git log 命令能夠顯示從最近到最遠的提交日誌,若是以爲輸出信息太多,可加上 --pretty=oneline 參數。

$ git log --pretty=oneline
0857d7f526f13b2a5eefdf73e811192bc9d63cb9 (HEAD -> master, origin/master, origin/HEAD) stage-4
100ff52732b102df98466bcceef550e24d9a5ce5 babel-loader
7d7643d2ea885c2a1332b25127eef497ca51869d babel
:           # 用 q 退出命令行

前面的一大串是提交記錄的哈希值,也就是 commit id,可經過 commit id 的前四五位字符肯定回退的版本。也可經過 HEAD 表明,HEAD 表示當前版本,也就是最新的提交 0857d...,上一個版本就是 HEAD^,上上一個版本就是 HEAD^^,往上 100 個版本可寫成HEAD~100

2. 經過 git reset 命令回退

$ git reset --hard HEAD^
HEAD is now at 100ff52 babel-loader

回退後,再 git log 就只能看到以前的提交記錄,而不能看到回退以前的最新提交,此時,若是要撤銷回退,就得找到最初的提交記錄的哈希值。可經過 git reflog 查看。 git reflog 可顯示全部的提交記錄。

$ git reflog
100ff52 (HEAD -> master) HEAD@{0}: reset: moving to HEAD^
0857d7f (origin/master, origin/HEAD) HEAD@{1}: commit: stage-4
100ff52 (HEAD -> master) HEAD@{2}: commit: babel-loader
7d7643d HEAD@{3}: commit: babel
:

得知,以前的提交記錄是 0857d,便可經過 git reset 恢復到最新提交。

$ git reset --hard 0857
HEAD is now at 0857d7f stage-4

Git 分支管理

1. 列出分支,帶 * 號的是當前分支

$ git branch   # 本地分支
* master

git branch -a 可列出本地和遠程的分支。

$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/gh-pages
  remotes/origin/master

上面的是本地分支,下方的有 remotes/origin 開頭的就是遠程分支。

2. 建立新分支 git branch <分支名>

$ git branch bugFix

建立好的分支須要和遠程分支關聯,可以使用:

$ git branch --set-upstream-to=origin/bugFix bugFix
# or
$  git branch --track origin/bugFix bugFix

3. 切換到新分支 git checkout <分支名>

$ git checkout bugFix   
$ git commit            # 先切換分支再提交,就會提交到新建的分支上

4. 建立並切換到新分支 git checkout -b <分支名>

$ git checkout -b bugFix

若是本地建立的分支須要和遠程的分支關聯,則可使用:

$ git checkout -b dev origin/dev

5. 合併分支

git merge <分支名>

$ git checkout master    # 切換到主分支
$ git merge bugFix       # 將 bugFix 分支合併到主分支上

merge 完若是有衝突,須要手動修改,而後再 add commit 告訴 Git 文件衝突已經解決。

合併分支時,Git會用 Fast forward 模式。若合併分支時,加上 --no-ff 參數就能夠用普通模式合併,合併後的歷史有分支,能看出來曾經作過合併,而 fast forward 合併就看不出來曾經作過合併。

git merge --no-ff -m "merged bugFix" bugFix

git rebase <分支名>

$ git checkout bugFix
$ git rebase master     # 將 bugFix 的提交記錄移動到 master分支上

$ git checkout master
$ git rebase bugFix     # 將 master 分支更新到移動過來的 bugFix 記錄上

6. 刪除分支

合併完後就能夠刪除分支 git branch -d <分支名>

$ git branch -d bugFix

若是要丟棄一個沒有被合併過的分支,須要經過 git branch -D <分支名> 強行刪除。

git branch -D feature

刪除遠程分支 git push origin --delete <分支名>

$ git push origin --delete gh-pages

7. 最新版本的 Git 提供了新的 git switch 命令來切換分支

$ git switch master    # 切換到已有分支
$ git switch -c dev    # 建立並切換到新的 dev 分支

將本地倉庫推送到遠程倉庫

1. 查看遠程倉庫

$ git remote -v

2. 鏈接遠程倉庫

經過 git remote add 命令鏈接 remote name (一般命名爲 origin)和遠程倉庫的 URL。

新建的本地倉庫若要推送到遠程倉庫,須要手動鏈接到要推送的遠程倉庫。

經過 git clone 克隆的遠程項目,已經創建了鏈接,就不須要再鏈接遠程倉庫了。直接先 pullpush 就能夠了。

$ git remote add origin URL

3. 修改遠程倉庫

$ git remote remove origin    # 先移除以前的倉庫
$ git remote add origin URL   # 再添加新的遠程倉庫

4. 推送

推送就是將已經提交到本地倉庫的那部份內容推送到遠程在線倉庫。修改了,但沒提交的那部份內容,不會被推送。

若鏈接到的遠程倉庫中有項目,則須要先 pull 再提交。

$ git pull origin master   # 若遠程倉庫中項目已存在,則須要先 pull,merge一下有衝突的部分。
$ git add .
$ git commit -m "init"   # 將本地有改動的文件提交到本地倉庫

將提交到本地倉庫的部份內容推送到遠程倉庫,或者若是遠程倉庫是空的,沒有項目,則可直接 push

$ git push -u origin master

遠程的名稱是 origin,默認的本地分支名稱是 master-u 是告訴 Git 記住這些參數,把本地的 master 分支和遠程的 master 分支關聯起來,以便下次能夠簡單地運行 git push,Git 就知道該怎麼作了。

若是本地 dev 要推送到遠程的 dev 分支,則使用:

$ git push origin dev

推送失敗,解決衝突

若是 push 失敗,提示有最新的提交,則表示有小夥伴已經提交過一個版本了,此時需先用 git pull 把最新的提交拉取下來,若是有衝突須要在本地先手動解決衝突,解決後,commit 提交,而後再推送。

若是解決完衝突後認爲提交分叉多比較亂,可在 push 前使用 git rebase 將分叉的提交變成一條直線,而後再推送。rebase 的目的是使得咱們在查看歷史提交的變化時更容易,由於分叉的提交須要三方對比。

5. 遠程回退

git revert 遠程撤銷

git revert 會提交一次新的提交記錄,該提交引入了更改,更改的內容就是回退撤銷到上一次提交。以後就能夠推送到遠程了。

$ git revert HEAD

git stash 存儲功能

存儲

git stash 會將當前工做區尚未提交到版本庫的更改存儲起來,但不會存儲新建的文件,由於新建的文件尚未被 Git 管理。工做區會回到上次 commit 的狀態,而且包含新建的文件。

$ git stash
Saved working directory and index state WIP on master: d21d76c git

$ git stash save "save message"    # git stash save 能夠添加說明文字

查看

git stash list 能夠查看儲存的列表。

$ git stash list
stash@{0}: WIP on master: d21d76c git

恢復儲存

恢復儲存的內容有兩種方法:

  • 一是用 git stash apply 恢復,可是恢復後,stash 內容並不刪除,你須要用 git stash drop 來刪除。
  • 另外一種方式是用 git stash pop,恢復的同時把 stash 內容也刪了。
$ git stash pop   # 默認第一個存儲

你能夠屢次 stash,恢復的時候,先用 git stash list 查看,而後恢復指定的 stash,用命令:

$ git stash apply stash@{0}
# or
$ git stash pop stash@{$num}

刪除存儲

$ git stash drop                  # 刪除第一條存儲
$ git stash drop stash@{$num}     # 刪除指定存儲項
$ git stash clear                 # 清空存儲列表

其它功能

在提交樹上移動指針

git checkout HEAD^
git checkout <提交記錄的哈希值>

強制修改分支位置

git branch -f master HEAD~3

上面的命令會將 master 分支強制指向 HEAD 的第 3 級父提交。

複製提交記錄到當前分支

知道提交記錄的哈希值時

$ git cherry-pick <提交記錄的哈希值> <...>

不知道提交記錄的哈希值

交互式 rebase 指的是使用帶參數 --interactive 的 rebase 命令, 簡寫爲 -i

若是你在命令後增長了這個選項, Git 會打開一個 UI 界面並列出將要被複制到目標分支的備選提交記錄,它還會顯示每一個提交記錄的哈希值和提交說明,提交說明有助於你理解這個提交進行了哪些更改。

在實際使用時,所謂的 UI 窗口通常會在文本編輯器 —— 如 Vim —— 中打開一個文件。

當 rebase UI界面打開時, 你能作3件事:

  • 調整提交記錄的順序
  • 刪除你不想要的提交
  • 合併提交。
git rebase -i HEAD~3

修改以前提交的某一個記錄

$ git rebase -i HEAD~2   # 先排序將須要修改的提交順序排到最新
$ git commit --amend     # 修改記錄
$ git rebase -i HEAD~2   #  再按照以前的順序排序

tag 標籤管理

發佈一個版本時,咱們一般先在版本庫中打一個標籤(tag),這樣,就惟一肯定了打標籤時刻的版本。未來不管何時,取某個標籤的版本,就是把那個打標籤的時刻的歷史版本取出來。因此,標籤也是版本庫的一個快照。

Git 的標籤雖然是版本庫的快照,但其實它就是指向某個 commit 的指針,然而標籤的指針不能移動,因此,建立和刪除標籤都是瞬間完成的。tag 就是一個讓人容易記住的有意義的名字,它跟某個 commit 綁在一塊兒。

git tag 建立標籤

在Git中打標籤很是簡單,首先,切換到須要打標籤的分支上。而後用 git tag <tagname> 就能夠打一個新標籤。

若是不指定提交記錄,Git 會用 HEAD 所指向的位置。

git tag v1.0 <提交記錄>

還能夠建立帶有說明的標籤,用 -a 指定標籤名,-m 指定說明文字:

$ git tag -a v1.0 -m "version 0.1 released" 0857d

查看標籤

git tag 查看標籤列表,git show <tagname> 可查看標籤信息

$ git tag
$ git show v1.0   # 查看標籤信息

推送標籤

$ git push origin <tagname>

或者,一次性推送所有還沒有推送到遠程的本地標籤:

git push origin --tags

刪除標籤

存儲在本地的標籤可直接刪除:

$ git tag -d v1.0

若是要刪除已經推送到遠程的標籤,須要先刪除本地,而後將本地的刪除推送到遠程:

$ git tag -d v1.0
$ git push origin :refs/tags/v1.0
相關文章
相關標籤/搜索