Git使用過程當中的一些常見場景問題總結

以前在公司內部推Git,寫了一份git使用教程,後來又在團隊內部作了一次分享,內容是關於Git使用過程當中常常會遇到的一些場景,並有了這份總結。git

git基礎

基於feature的工做流github

  • 添加忽略文件 .gitignore (gitignore.io/)
  • 基於develop分支開發:feature分支 bugfix分支 版本節點tag
  • 問題排查: diff 、log 、reflog、blame
  • 撤銷操做: checkout 、reset、revert、commit --amend
  • 刪除操做: rm clean
  • 儲藏操做: stash
  • 分支操做:建立、刪除(注意遠程分支的刪除)、切換、合併(--no-ff 、rebase)
  • 標籤操做

更多詳細查看上面教程連接shell

場景

1. 本地已經存在的項目/分支與如何遠程倉庫關聯

git remote add origin <your-repo-git-url>
複製代碼

2. 剛剛提交了的commit log發現錯了,想修改

git commit --amend -m "your new log"
複製代碼

3. 查看某次提交的日誌和ID

git reflog
複製代碼

4. 查看某次提交的內容

git show <commit_id>
複製代碼

5. 只是修改了工做區的文件,想恢復到原來修改前的樣子

git reset --hard HEAD
git checkout -- <file_name>
複製代碼

6. 被修改的文件已經添加到了暫存區,想撤銷添加

git reset --mixed HEAD
複製代碼

7. 被修改的文件已經commit提交,想撤銷提交

git reset --soft HEAD^
複製代碼

8. 已經提交到遠程主機的文件,想撤銷

git revert <commit_id>
git revert HEAD
複製代碼

9. 已經開發一半的功能,可是沒有開發完,這時候有個bug要緊急處理,須要放下手頭的功能,趕去修改BUG

// 保存現場
git stash  
// 恢復現場
git stash pop
複製代碼

10. 加入過歷史版本的文件,因某些緣由被刪除了想恢復

git checkout <commit_id> -- <file_name>
複製代碼

另外你也能夠用reset命令來完成bash

11. 須要單獨把屢次提交中的某一次提交從你的分支遷移到另一個分支上,即跨分支應用commit

git cherry-pick <commit_id>
複製代碼

好比:我想把如下分支工具

A-B  master
   \
    C-D-E-F-G develop
複製代碼

中的D,F 兩次提交移動到master分支,而保持其餘commit不變,結果就像這樣學習

A-B-D-F  master
       \
        C-E-G develop
複製代碼

那麼,思路是將D,F 用cherry-pick應用到master分支上,而後將develop分支對master分支變基。fetch

$ git checkout master  
$ git cherry-pick D  
$ git cherry-pick F  
$ git checkout develop  
$ git rebase master
複製代碼

注意有些狀況下使用cherry-pick會存在衝突,解決方法和咱們平時合併分支遇到衝突同樣。網站

12. 遇到文件衝突,能夠手動解決,或者用你配置的工具解決,記得把文件標位resolved:add/rm

如:常見的拉取同事的代碼合併引發衝突this

1. 手動處理衝突
2. 文件標誌位置爲resolved:git add <file_name>
3. 繼續合併  git merge --continue
固然也能夠選擇放棄合併:git merge --abort
複製代碼

13. 讓本身本地分支上面的每一次提交日誌變得更有意義,有時候須要咱們選擇有意義的提交日誌信息合併上去

好比咱們在bugfix分支上面因爲修改bug提交了不少次,修復好了以後,咱們想把這些提交合併入咱們的master分支url

git checkout master
git merge --squash bugfix
git commit -m "bug fixed"
複製代碼

上面操做會將bugfix分支上的全部commit都合併爲一個commit,並把它併入咱們的master分支上去。這裏還有一點須要注意的是:--squash含義表明的是本地內容與不使用該選項的合併結果相同,可是不提交,不移動HEAD指針,因此咱們要另外多一條語句來移動咱們的HEAD指針,即最後的commit。

14. 有時候須要整理咱們本地的commits,可使用Squash

git rebase -i <commit>
複製代碼

舉例:

git rebase -i HEAD~5

執行完後,Git會把全部commit列出來,讓你進行一些修改,修改完成以後會根據你的修改來rebase。HEAD-5的意思是隻修改最近的5個commit。

pick 033beb4 b1
pick b426a8a b2
pick c216era b3
pick d627c9a b4
pick e416c8b b5

# Rebase 033beb4..e416c8b onto 033beb4
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
複製代碼

上面pick是要執行的commit指令,另外還有reword、edit、squash、fixup、exec這5個,具體的含義能夠看上面的註釋解釋,比較簡單,這裏就不說了。 咱們要合併就須要修改前面的pick指令:

pick 033beb4 b1
squash b426a8a b2
squash c216era b3
squash d627c9a b4
squash e416c8b b5
複製代碼

也就是下面這4個提交合併到最前面的那個提交裏面,按esc,打上:wq提交保存離開。 接着是輸入新的commit message

b
# This is a combination of 2 commits.
# The first commit's message is:
# b1
#
# This is the 2nd commit message:
#
# b2
#
# This is the 3rd commit message:
#
# b3
#
# This is the 4th commit message:
#
# b4
#
# This is the 5th commit message:
#
# b5
#
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# Not currently on any branch.
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: a.txt
#
複製代碼

其中第一行的b就是須要咱們輸入的新信息,一樣編輯完保存,出現相似下面的信息:

Successfully rebased and updated refs/heads/develop.
複製代碼

最後能夠用git log指令來驗證commits是否是咱們要變成的樣子。

15. 多人協做開發項目,想知道某個文件的當前改動狀況

一般查問題時想知道某個文件的某部分代碼是誰改動的,那麼git blame 就派上用場了。

git blame <file_name>
複製代碼

你也能夠具體指定到某一行或者某幾行代碼

git blame -L <start_line>,<end_line> <file_name>
複製代碼

16. 執行push命令向多個倉庫同時提交代碼

有時候會作代碼備份,將代碼保存在幾個不一樣的Git代碼管理平臺,這時候就須要用到了

修改本地倉庫目錄下.git/config文件

[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
	ignorecase = true
	precomposeunicode = true
[remote "origin"]
	url = git@github.com:yuxingxin/blog.git
    url = ……
    url = ……
	fetch = +refs/heads/*:refs/remotes/origin/*
複製代碼

如上 在remote處能夠添加多個遠程地址。

17. 從屢次提交中快速定位某一次提交的bug

# 開始 bisect
$ git bisect start

# 錄入正確的 commit
$ git bisect good xxxxxx

# 錄入出錯的 commit
$ git bisect bad xxxxxx

# 而後 git 開始在出錯的 commit 與正確的 commit 之間開始二分查找,這個過程當中你須要不斷的驗證你的應用是否正常
$ git bisect bad
$ git bisect good
$ git bisect good
...

# 直到定位到出錯的 commit,退出 bisect
$ git bisect reset
複製代碼

總結

固然了,git的一些常見場景,還遠不止這些,限於本人能力有限,若是你在平時的工做中遇到一些很實用的命令,也歡迎反饋給我,我好一併學習。更多的詳細能夠參考以前總結的一系列文檔: devops.yuxingxin.com。 學習git命令是一件頗有意思的事情,我想它能幫助使用git命令的人更好的理解這一代碼管理工具,從而不至於犯一些低級錯誤,MobDevGroup網站上面也分享過幾個學習命令的網站,能夠供參考:mobdevgroup.com/tools/assis…

相關文章
相關標籤/搜索