2021-05-12 14:32:11
Git命令和設定技巧
此文主要介紹一切開發中常用的git命令和一些設定技巧(諸如git別名設定,log列印技巧,版本回退以及分支管理等)。
1.簡介
Git與svn相比而言,Git的好處自然不用多說,Git完全分散式檔案管理系統,加上其簡單速度,可以高效管理類似 Linux 核心一樣的超大規模專案。完全分散式的系統,讓你可以在公交車上,火車上,家中,甚至在廁所都可以敲程式碼。何時何地你都可以敲程式碼,甚至不需要網路。好不好使,開不開心?換是SVN,SVN伺服器掛了,全部人停止敲程式碼,停下來八卦去吧。
Git 和其他版本控制系統的主要差別在於,Git 只關心檔案資料的整體是否發生變化,而大多數其他系統則只關心檔案內容的具體差異。這類系統(CVS,Subversion,Perforce,Bazaar 等等)每次記錄有哪些檔案作了更新,以及都更新了哪些行的什麼內容。如同下圖所示:
但是,Git 並不儲存這些前後變化的差異資料。實際上,Git 更像是把變化的檔案作快照後,記錄在一個微型的檔案系統中。每次提交更新時,它會縱覽一遍所有檔案的指紋資訊並對檔案作一快照,然後儲存一個指向這次快 照的索引。為提高效能,若檔案沒有變化,Git 不會再次儲存,而只對上次儲存的快照作一連線。工作方式類似下圖:
對比可以發現,Git高效也在情理之中。
現在再簡單介紹一下Git管理下檔案的三種狀態。對於任何一個檔案,只要在Git管理下,那麼該檔案只有三種狀態:已修改(modified),已暫存(staged)和已提交 (committed)。
已修改(modified): 檔案被修改,但是還沒有提交儲存(也就是沒有使用git add,此時使用git status顯示為紅色)。
已暫存(staged): 已修改的檔案放入下次要提交的清單中(使用了git add後的狀態,此時使用git status顯示為綠色)。
已提交(committed): 該檔案已經被安全地儲存在本地資料庫中(使用了git commit後,此時使用git status已經不存在該檔案的任何資訊)。
具體可以參考下面兩幅圖來理解。
2.設定使用者資訊
user和email,--global引數全域性設定,當然你也可以不加此引數,不同的專案用不同的使用者名稱和郵箱。
git config --global user.name Super
git config --global user.email 1342449****@163.com
3.設定全域性別名
此設定在開發中相當重要,尤其是對於使用Terminal,習慣使用命令列的朋友,由於git不支援tab自動補全,每次想要看下工作目錄 狀態都要git status,相當耗時。除非你能確定你敲兩個字母比六個字母用時少。
git config --global alias.st "status -s"
git config --global alias.ci "commit -m"
git config --global alias.aci "commit -a -m" // 跳過使用暫緩區,直接將git add和git commit合併為一條命令
git config --global alias.lg "log --color --pretty=format:'%Cred%h - %Cgreen%an %C(yellow)| %ad | %Creset%s' --graph" (自定義log)
第一條:git status是開發中使用最多最頻繁的,至於-s 是簡潔輸入(Give the output in the short-format)
第二條:此條也使用頻繁,但是我在開發中直接使用第三條跳過。
第三條:設定git aci 因為這樣直接跳過使用暫存區域,對於已經跟蹤的檔案,我不要再此次使用git add加入暫緩區,然後再git commit提交到本地資料庫,為了方便省事,直接將兩條命令合併為一條,使用git aci "提交說明" 即可。省不省事,用下自然知道。
第四條:這裡是我自定義的log資訊,當然,一會看完本文你也可以自己格式化成自己喜歡的log格式。可以先看下效果,下圖所示:
以後直接使用"git lg"即可,非常方便,顯示簡潔明瞭。
4.分支管理
git checkout -b dev origin/dev // 拉取遠端開發分支到本地並且切換到開發分支
git push dev origin/dev
git branch new // 建立新分支
git push origin new // 將new分支推播到遠端(git push [remote-name] [branch-name])
git push origin :new // 刪除遠端分支,注意冒號位置
git brach -d new // 刪除本地分支,如果有沒有merge的資訊,確保該分支的確不用merge,直接使用-D強行刪除
git merge dev // 將dev分支合併到當前分支
git checkout master // 切換到主分支
// 其他不再一一列出
關於實際開發中,獨立開發的話其實兩個分支完全夠用,一個主分支,一個開發分支。多人的話就按功能模組和人員來具體新建分支即可。由於這邊由我一人負責整個專案,那麼分支的話,我就建立了一個develop分支。發布版本時放到主分支處理即可。平時都在develop分支開發,如果此時發現線上版本有bug,那麼只需要切換到master分支,修改bug,然後封版即可。處理好後繼續回到開發分支開發就可以了。當然最好還是把剛才修改bug的程式碼merge到開發分支上。
還有一點使用技巧,也就是git stash的靈活使用。當我們正在當前分支編寫程式碼,突然某人中斷你的思路,提出某功能需修改且比較緊急,更煩人的是當前的程式碼已經開始編寫,而且動用了好多檔案,重要的是不想中途進行git commit提交。此時git stash就發揮作用了。
git stash // 暫時隱藏,之後就可以正常切換分支了,當前的修改內容只是儲存並且隱藏起來
git stash pop // 回復到之前的工作狀態,預設pop的是最近的一條,這樣就可以愉快的繼續編寫當時被中斷的程式碼了
git stash可以執行多次,我們可以使用git stash list命令來檢視清單。當然還有好多命令,可以使用"git stash --help"來檢視。
// git stash --help
usage: git stash list [<options>]
or: git stash show [<stash>]
or: git stash drop [-q|--quiet] [<stash>]
or: git stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]
or: git stash branch <branchname> [<stash>]
or: git stash [save [--patch] [-k|--[no-]keep-index] [-q|--quiet]
[-u|--include-untracked] [-a|--all] [<message>]]
or: git stash clear
其實關於git stash還有一個使用技巧,那就是如果當前改了眾多檔案,突然又不想改了,想恢復到原來的樣子。那麼可能你會使用"git checkout ."命令來取消所有的更改,但是有種情況並不好使,那就是你除了修改檔案,還新增了一些檔案或則拖入了一些檔案到工程目錄下,此時使用"git checkout ."然後再使用"git status"檢視的時候,會發現工作區多出了尚未識別的檔案(處於等待add的狀態)。在這個時候,使用git stash是再好不過了,因為這樣將所有git控制下的檔案,包括之前的目錄,全部還原到之前的狀態(也就是說git stash把新增的檔案也暫時隱藏起來)。如果想徹底刪掉,那就再把所有stash的列表清空吧,直接"git stash list"看下,然後"git stash clear"。
還有一點,關於在Git伺服器上刪除分支,本地使用"git branch -a"依舊可以看到被刪除問題。好比你的程式碼託管到了開源中國(OSChina),你通過網站,線上刪除分支,就會出現這種問題,稍微有點強迫症的自然受不了。此時可以使用 "git fetch -p"使fetch之後刪除沒有與遠端分支對應的本地分支。 當然也可以通過檢視遠端分支。使用命令"git remote show origin"顯示如下:
YJTSuper:yjtim super$ git remote show origin
* remote origin
Fetch URL: git@git.oschina.net:lingsui/yjtim.git
Push URL: git@git.oschina.net:lingsui/yjtim.git
HEAD branch: master
Remote branches:
dev tracked
im tracked
master tracked
proV2.3.0 tracked
refs/remotes/origin/test stale (use 'git remote prune' to remove)
Local branches configured for 'git pull':
master merges with remote master
show merges with remote master
Local refs configured for 'git push':
dev pushes to dev (up to date)
im pushes to im (fast-forwardable)
master pushes to master (up to date)
proV2.3.0 pushes to proV2.3.0 (up to date)
我們可以看到分支origin/test 已經過期(stale),可以使用命令"git remote prune origin"同樣可以處理。
5.遠端地址切換
如果想要切換遠端地址,千萬不要重新再初始化一個git程式碼倉庫,使用git add重新新增。這樣的好處只有一點,所有歷史提交資訊全部清空,不再保留,"git clone"時檔案變小,理所當然,歷史記錄全部清空了麼。如果確定不保留,也建議這樣做,關鍵時,誰寫的程式碼更改了哪些東西很重要呀,還是選擇保留吧。使用下面的方法,一行程式碼搞定,並且保留了所有的commit記錄。
git remote -v // 檢視遠端地址
git remote set-url origin https://git.oschina.net/HaiShengHuo/xxx.git // 更換遠端地址, 新建一個專案不新增任何檔案 在本地直接push即可
6.檢視某次提交修改的具體檔案
方法一
git reflog
列出最新修改記錄 也可以 git log --onelinegit log 00788a04 --name-status
找到對應版本號 執行
commit 00788a04f8d6dd834723c3479a0b5cdcfad8694a
Author: ZhiChao <13424490552@163.com>
Date: Thu Mar 30 11:04:46 2017 +0800
最後一條訊息顯示來源人
M yjtim/IM/Chat/Controller/ConversationListController.m
commit a4b9129f1728dc10d5f6ab8c77c1b20ef7bb3d12
Author: ZhiChao <13424490552@163.com>
Date: Wed Mar 29 17:49:44 2017 +0800
隱藏被入群彈框
M yjtim/IM/Chat/Controller/ChatDemoHelper.m
commit 1910008369d4ab264e7610997135a54d27fe22c7
Author: ZhiChao <13424490552@163.com>
Date: Wed Mar 29 17:40:56 2017 +0800
99+
M yjtim/IM/EaseUI/EMUIKit/Views/conversation/toolbar/EaseImageView.m
git diff HEAD@{79} HEAD@{78}
具體某次修改的內容(具體某次內容和上次的內容進行比較)git diff a4b9129f 00788a04
當然也可以使用版本號
這樣假如之前修改過具體某些內容,以後還需要修改的話,找起來真的很方便.好比某些bug好久之後才發現,又要回頭去修改,而修改總要找到對應的程式碼進行修改吧,這樣幾行命令就定位到具體檔案和位置了,方便多了,節省很多時間.找程式碼有技巧,但是"找"終究還是很浪費時間.這也告訴我們,commit 提交命令很重要,需要認真寫,不可為了省事而亂寫
diff --git a/yjtim/IM/Chat/Controller/ConversationListController.m b/yjtim/IM/Chat/Controller/ConversationListController.m
index df0555e5..71822638 100644
--- a/yjtim/IM/Chat/Controller/ConversationListController.m
+++ b/yjtim/IM/Chat/Controller/ConversationListController.m
@@ -347,7 +347,7 @@ - (NSAttributedString *)conversationListViewController:(EaseConversationListView
[attributedStr setAttributes:@{NSForegroundColorAttributeName : [UIColor colorWithRed:1.0 green:.0 blue:.0 alpha:0.5]} range:NSMakeRange(0, NSLocalizedString(@"group.atMe", @"[Somebody @ me]").length)];
}
else {
- attributedStr = [[NSMutableAttributedString alloc] initWithString:latestMessageTitle];
+ attributedStr = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@:%@",[[YJTAddressList shareAddressList].userNameDict objectForKey:lastMessage.from],latestMessageTitle]];
}
}
方法二
直接使用git log 6b81a31033 -p
或則 git log -p 6b81a31033
其中6b81a31033為版本雜湊值
commit 6b81a31033074ef279049e9cbf5944e3158d7510
Author: ZhiChao <13424490552@163.com>
Date: Fri Apr 14 13:57:22 2017 +0800
綜合評價fixbug
diff --git a/yjtim/Sections/Apps/NewEvaluation/Controller/YJTEvaDetailVC.m b/yjtim/Sections/Apps/NewEvaluation/Controller/YJTEvaDetailVC.m
index 10ff4b31..cef73191 100644
--- a/yjtim/Sections/Apps/NewEvaluation/Controller/YJTEvaDetailVC.m
+++ b/yjtim/Sections/Apps/NewEvaluation/Controller/YJTEvaDetailVC.m
@@ -28,7 +28,7 @@ @interface YJTEvaDetailVC ()<YJTEvaDateSelectVCDelegate>
@property (nonatomic, strong) NSArray *catListArray;
@property (nonatomic, strong) YJTEvaSchoolYearModel *evaSchoolYearModel;
-
+@property (nonatomic, copy) NSString *formId;
@property (nonatomic, copy) NSString *className;
@property (nonatomic, copy) NSString *classId;
@property (nonatomic, copy) NSString *tempClassId;
@@ -262,6 +262,7 @@ - (void)rightBtnClick {
editVC.evaListModel = self.evaListModel;
editVC.catListArray = self.catListArray;
...
方法三
git log --stat 6b81a31033
或者git log 6b81a31033 --stat
檢視簡潔檔案變化
commit 6b81a31033074ef279049e9cbf5944e3158d7510
Author: ZhiChao <13424490552@163.com>
Date: Fri Apr 14 13:57:22 2017 +0800
綜合評價fixbug
yjtim/Sections/Apps/NewEvaluation/Controller/YJTEvaDetailVC.m | 5 +++--
yjtim/Sections/Apps/NewEvaluation/Controller/YJTEvaEditVC.h | 1 +
yjtim/Sections/Apps/NewEvaluation/Controller/YJTEvaEditVC.m | 2 +-
3 files changed, 5 insertions(+), 3 deletions(-)
7.忽略跟蹤
git checkout . 清空所有更改
以下命令是我們在專案中已經新增了.gitignore 但是中途突然不想再跟蹤某檔案
此時發現簡單的在.gitignore檔案中新增要忽略的檔案是不起效的,因為該檔案已
經被track,我們還需要將其狀態改為 未track(其實只需刪除暫緩區檔案然後將操作體檢即可)
git rm --cached Podfile.lock 將Podfile.lock從暫緩區刪除,不再跟蹤
8.備份
備份的話好一些,每次新的版本打一次tag,檢視起來還是挺方便。不過不用也行。我不愛使用這個。
git tag -a WeChat1.0 -m "version 1.0" :給版本打上標籤
git tag : 檢視所有的標籤
git push origin WeChat1.0 : 將WeChat1.0 push 到預設分支
9.版本回退
git reset --hard HEAD // 沒有提交的情況下進行版本回退
git reset --hard HEAD^ // 回退到上一個版本
git reset --hard HEAD^^ // 回退到指定回退到某個版本
git reset --hard 版本號(至少前5位) // 回退到前幾個版本
git reset --hard~1
git revert c011eb3c20ba6fb38cc94fe5a8dda366a3990c61 // 注意該行命令 reset和revert有本質區別
注意:開發中一般受控代碼到遠端程式碼倉庫,比如Github或則OSChina,加入本地已經使用git push到遠端程式碼倉庫,在本地使用git reset回退再push明顯是不可行的。因為git reset直接回退到歷史中的某個Hash值,但是使用git revert就不一樣了。git revert將作為一次新提交(新的Hash值)而不是歷史中的某個Hash值,此時再push到遠端程式碼倉庫情理之中。
10.紀錄檔
想回顧下提交歷史,可以使用 git log 命令,其中有個--pretty 引數可以設定git log --pretty=oneline
git log --pretty=format:"%h - %an, %ar : %s"
git log --pretty=format:"%h %s" --graph
git log --since=2.weeks
自己可以試一下,這裡附上引數說明,自己可以隨意設定,當然log字型顏色也都是可以修改的,不再細述。
選項 | 說明 |
---|---|
%H | 提交物件(commit)的完整雜湊字串 %h 提交物件的簡短雜湊字串 ..................................................................................................... |
%T | 樹物件(tree)的完整雜湊字串 |
%t | 樹物件的簡短雜湊字串 |
%P | 父物件(parent)的完整雜湊字串 %p 父物件的簡短雜湊字串 |
%an | 作者(author)的名字 |
%ae | 作者的電子郵件地址 |
%ad | 作者修訂日期(可以用 -date= 選項客製化格式) %ar 作者修訂日期,按多久以前的方式顯示 |
%cn | 提交者(committer)的名字 |
%ce | 提交者的電子郵件地址 |
%cd | 提交日期 |
%cr | 提交日期,按多久以前的方式顯示 %s 提交說明 |
時間和提交者過濾
選項 | 說明 |
---|---|
-(n) | 僅顯示最近的 n 條提交.................................................................................................................................................... |
--since, --after | 僅顯示指定時間之後的提交。 |
--until, --before | 僅顯示指定時間之前的提交。 |
--author | 僅顯示指定作者相關的提交。 |
--committer | 僅顯示指定提交者相關的提交。 |
你一定奇怪_作者(author)_和_提交者(committer)_之間究竟有何差別,其實作者指的是實際作出修改 的人,提交者指的是最後將此工作成果提交到倉庫的人。所以,當你為某個專案發去修補程式,然後某個核心成員將你的修補程式併入專案時,你就是作者,而那個核心成員就是提交者。我們會在第五章再詳細介紹兩者之間的細緻差別。
11.忽略某些檔案
檔案 .gitignore 的格式規範如下:
• 所有空行或者以注釋符號 # 開頭的行都會被 Git 忽略。
• 可以使用標準的 glob 模式匹配。
• 匹配模式最後跟反斜槓(/)說明要忽略的是目錄。
• 要忽略指定模式以外的檔案或目錄,可以在模式前加上驚嘆號(!)取反。
所謂的 glob 模式是指 shell 所使用的簡化了的正規表示式。星號(*)匹配零個或多個任意字元;[abc] 匹配 任何一個列在方括號中的字元(這個例子要麼匹配一個 a,要麼匹配一個 b,要麼匹配一個 c);問號(?) 只匹配一個任意字元;如果在方括號中使用短劃線分隔兩個字元,表示所有在這兩個字元範圍內的都可以匹配 (比如 [0-9] 表示匹配所有 0 到 9 的數位)。
# 此為註釋 – 將被 Git 忽略
*.[oa] Git 忽略所有以 .o 或 .a 結尾的檔案。一般這類物件檔案和存檔檔案都是編譯過程中出現 的,我們用不著跟蹤它們的版本
*~ Git 忽略所有以波浪符(~)結尾的檔案,許多文字編輯軟體 (比如 Emacs)都用這樣的檔名儲存副本
*.a # 忽略所有 .a 結尾的檔案
!lib.a # 但 lib.a 除外
/TODO # 僅僅忽略專案根目錄下的 TODO 檔案,不包括 subdir/TODO build/ # 忽略 build/ 目錄下的所有檔案
doc/*.txt # 會忽略 doc/notes.txt 但不包括 doc/server/arch.txt
更多 Git 教學系列文章:
GitHub 使用教學圖文詳解 http://www.linuxidc.com/Linux/2014-09/106230.htm
Git使用圖文詳細教學 http://www.linuxidc.com/Linux/2016-11/136781.htm
Ubuntu Git安裝與使用 http://www.linuxidc.com/Linux/2016-11/136769.htm
Git 標籤管理???解 http://www.linuxidc.com/Linux/2014-09/106231.htm
Git 分支管理詳解 http://www.linuxidc.com/Linux/2014-09/106232.htm
Git 遠端倉庫詳解 http://www.linuxidc.com/Linux/2014-09/106233.htm
Git 本地倉庫(Repository)詳解 http://www.linuxidc.com/Linux/2014-09/106234.htm
Git 伺服器搭建與用戶端安裝 http://www.linuxidc.com/Linux/2014-05/101830.htm
Git 概述 http://www.linuxidc.com/Linux/2014-05/101829.htm
分享實用的GitHub 使用教學 http://www.linuxidc.com/Linux/2014-04/100556.htm
Git從入門到學會 http://www.linuxidc.com/Linux/2016-10/135872.htm
Git基本操作詳解 http://www.linuxidc.com/Linux/2016-10/135691.htm
Git部署與常用基本命令詳解 http://www.linuxidc.com/Linux/2017-06/144961.htm
分散式版本控制系統 Git 詳細教學 http://www.linuxidc.com/Linux/2017-05/143747.htm
相關文章