標籤:
忽略某些檔案1.忽略某些檔案
項目中經常會產生一些Git系統不需要追蹤(track)的檔案。典型的是在編譯產生過程中產生的檔案或是編程器產生的臨機操作備份檔案。當然,你不追蹤(track)這些檔案,可以 平時不用"git add"去把它們加到索引中。 但是這樣會很快變成一件煩人的事,你發現 項目中到處有未追蹤(untracked)的檔案; 這樣也使"git add ." 和"git commit -a" 變得實際上沒有用處,同時"git status"命令的輸出也會有它們。 你可以在你的頂層工作目錄中添加一個叫".gitignore"的檔案,來告訴Git系統要忽略掉哪些檔案,下面是檔案內容的樣本: 以‘#‘ 開始的行,被視為注釋。 忽略掉所有檔案名稱是 foo.txt 的檔案。
foo.txt
忽略所有產生的 html 檔案。
*.html
foo.html是手工維護的,所以例外。
!foo.html
忽略所有.o 和 .a檔案。
*.[oa]
三、rebase1.rebase
假設你現在基於遠程分支"origin",建立一個叫"mywork"的分支。
$ git checkout -b mywork origin
現在我們在這個分支做一些修改,然後產生兩個提交(commit)。
$ vi file.txt$ git commit$ vi otherfile.txt$ git commit
但是與此同時,有些人也在"origin"分支上做了一些修改並且做了提交了。這就意味著"origin"和"mywork"這兩個分支各自"前進"了,它們之間"分叉"了。 在這裡,你可以用"pull"命令把"origin"分支上的修改拉下來並且和你的修改合并; 結果看起來就像一個新的"合并的提交"(merge commit): 但是,如果你想讓"mywork"分支曆史看起來像沒有經過任何合并一樣,你也許可以用git rebase:
$ git checkout mywork$ git rebase origin
這些命令會把你的"mywork"分支裡的每個提交(commit)取消掉,並且把它們臨時儲存為補丁(patch)(這些補丁放到".git/rebase"目錄中),然後把"mywork"分支更新 到最新的"origin"分支,最後把儲存的這些補丁應用到"mywork"分支上。 當‘mywork‘分支更新之後,它會指向這些新建立的提交(commit),而那些老的提交會被丟棄。 如果運行垃圾收集命令(pruning garbage collection), 這些被丟棄的提交就會刪除。 在rebase的過程中,也許會出現衝突(conflict). 在這種情況,Git會停止rebase並會讓你去解決衝突;在解決完衝突後,用"git-add"命令去更新這些內容的索引(index), 然後,你無需執行 git-commit,只要執行:
$ git rebase --continue
這樣git會繼續應用(apply)餘下的補丁。 在任何時候,你可以用--abort參數來終止rebase的行動,並且"mywork" 分支會回到rebase開始前的狀態。
$ git rebase --abort
四、互動式rebase1.互動式rebase
你亦可以選擇進行互動rebase。這種方法通常用於在向別處推送提交之前對它們進行重寫。互動式rebase提供了一個簡單易用的途徑讓你在和別人分享提交之前對你的提交進行分割、合并或者重排序。在把從其他開發人員處拉取的提交應用到本地時,你也可以使用互動式rebase對它們進行清理。 如果你想在rebase的過程中對一部分提交進行修改,你可以在‘git rebase‘命令中加入‘-i‘或‘--interactive‘參數去調用互動模式。
$ git rebase -i origin/master
這個命令會執行互動式rebase操作,操作對象是那些自最後一次從origin倉庫拉取或者向origin推送之後的所有提交。 若想查看一下將被rebase的提交,可以用如下的log命令:
$ git log github/master..
一旦你完成對提交資訊的編輯並且退出編輯器,這個新的提交及提交資訊會被儲存起來。 如果指定進行‘edit‘操作,git會完成同樣的工作,但是在對下一提交進行操作之前,它會返回到命令列讓你對提交進行修正,或者對提交內容進行修改。 例如你想要分割一個提交,你需要對那個提交指定‘edit‘操作: 你會進入到命令列,撤銷(revert)該提交,然後建立兩個(或者更多個)新提交。假設提交21d80a5修改了兩個檔案,file1和file2,你想把這兩個修改放到不同的提交裡。你可以在進入命令列之後進行如下的操作:
$ git reset HEAD$ git add file1$ git commit -m ‘first part of split commit‘$ git add file2$ git commit -m ‘second part of split commit‘$ git rebase --continue
互動式rebase的最後一個作用是丟棄提交。如果把一行刪除而不是指定‘pick‘、‘squash‘和‘edit‘中的任何一個,git會從曆史中移除該提交
五、互動式添加1.互動式添加
互動式添加提供友好的介面去操作Git索引(index),同時亦提供了可視化索引的能力。只需簡單鍵入‘git add -i‘,即可使用此功能。Git會列出所有修改過的檔案及它們的狀態。
$ git add -i
在這個例子中,我們可以看到有5個修改過的檔案還沒有被加入到索引中(unstaged),甚至可以看到每個檔案增加和減少的行數。緊接著是一個互動菜單,列出了我們可以在此模式中使用的命令。 如果我們想要暫存(stage)這些檔案,我們可以鍵入‘2‘或者‘u‘進入更新(update)模式。然後我們可以通過鍵入檔案的範圍(本例中是1-4)來決定把哪些檔案加入到索引之中。
What now> 2 staged unstaged path 1: unchanged +4/-0 assets/stylesheets/style.css 2: unchanged +23/-11 layout/book_index_template.html 3: unchanged +7/-7 layout/chapter_template.html 4: unchanged +3/-3 script/pdf.rb 5: unchanged +121/-0 text/14_Interactive_Rebasing/0_ Interactive_Rebasing.markdownUpdate>> 1-4 staged unstaged path* 1: unchanged +4/-0 assets/stylesheets/style.css* 2: unchanged +23/-11 layout/book_index_template.html* 3: unchanged +7/-7 layout/chapter_template.html* 4: unchanged +3/-3 script/pdf.rb 5: unchanged +121/-0 text/14_Interactive_Rebasing/0_ Interactive_Rebasing.markdownUpdate>>
如果鍵入斷行符號,我會回到主菜單中,同時可以看到那些指定檔案的狀態已經發生了改變:
What now> status staged unstaged path 1: +4/-0 nothing assets/stylesheets/style.css 2: +23/-11 nothing layout/book_index_template.html 3: +7/-7 nothing layout/chapter_template.html 4: +3/-3 nothing script/pdf.rb 5: unchanged +121/-0 text/14_Interactive_Rebasing/0_ Interactive_Rebasing.markdown
現在我們可以看到前4個檔案已經被暫存,但是最後一個沒有。基本上,這是一個更加緊湊的查看狀態的方式,實質上的資訊與我們在命令列中運行‘git status‘是一致的:
$ git status
六、儲藏1.儲藏
當你正在做一項複雜的工作時, 發現了一個和當前工作不相關但是又很討厭的bug. 你這時想先修複bug再做手頭的工作, 那麼就可以用 git stash 來儲存當前的工作狀態, 等你修複完bug後,執行‘反儲藏‘(unstash)操作就可以回到之前的工作裡。
$ git stash save "work in progress for foo feature"
上面這條命令會儲存你的本地修改到儲藏(stash)中, 然後將你的工作目錄和索引裡的內容全部重設, 回到你當前所在分支的上次提交時的狀態。 好了, 你現在就可以開始你的修複工作了。
$ git commit -a -m "blorpl: typofix"
當你修複完bug後, 你可以用git stash apply來回複到以前的工作狀態。
$ git stash apply
2.儲藏隊列
你也可多次使用‘git stash‘命令, 每執行一次就會把針對當前修改的‘儲藏’(stash)添加到儲藏隊列中. 用‘git stash list‘命令可以查看你儲存的‘儲藏‘(stashes):
$ git stash list
可以用類似‘git stash apply [email protected]{1}‘的命令來使用在隊列中的任意一個‘儲藏‘(stashes). ‘git stash clear‘則是用來清空這個隊列。
七、Git樹名1.Git樹名
不用40個位元組長的SHA串來表示一個提交(commit)或是其它git對象,有很多種名字表示方法。在Git裡,這些名字就叫‘樹名‘(treeish)
2.Sha短名
如果你的一個提交(commit)的sha名字是 ‘980e3ccdaac54a0d4de358f3fe5d718027d96aae‘, git會把下面的串視為等價的:
980e3ccdaac54a0d4de358f3fe5d718027d96aae980e3ccdaac54a0d4980e3cc
只要你的‘sha短名’(Partial Sha)是不重複的(unique),它就不會和其它名字衝突(如果你使用了5個位元組以上那是很難重複的),git也會把‘sha短名’(Partial Sha)自動補全。
3.分支, Remote 或 標籤
你可以使用分支,remote或標籤名來代替SHA串名, 它們只是指向某個對象的指標。假設你的master分支目前在提交(commit):‘980e3‘上, 現在把它推送(push)到origin上並把它命名為標籤‘v1.0‘, 那麼下面的串都會被git視為等價的:
980e3ccdaac54a0d4de358f3fe5d718027d96aaeorigin/masterrefs/remotes/origin/mastermasterrefs/heads/masterv1.0refs/tags/v1.0
這意味著你執行下面的兩條命令會有同樣的輸出:
$ git log master$ git log refs/tags/v1.0
4.日期標識符
Git的引用日誌(Ref Log)可以讓你做一些‘相對‘查詢操作
master@{yesterday}[email protected]{1 month ago}:
上面的第一條命令是:‘master分支的昨天狀態(head)的縮寫‘。注意: 即使在兩個有相同master分支指向的倉庫上執行這條命令, 但是如果這個兩個倉庫在不同機器上, 那麼執行結果也很可能會不一樣。
5.順序標識符
這種格式用來表達某點前面的第N個提交(ref)。
master@{5}
上面的運算式代表著master前面的第5個提交(ref)。
6.多個父物件
這能告訴你某個提交的第N個直接父提交(parent)。這種格式在合并提交(merge commits)時特別有用, 這樣就可以使提交對象(commit object)有多於一個直接父物件(direct parent)。
master^2
7.波浪號
波浪號用來標識一個提交對象(commit object)的第N級嫡(祖)父物件(Nth grandparent)。 例如:
master~2
就代表master所指向的提交對象的第一個父物件的第一個父物件(譯者:你可以理解成是嫡系爺爺:))。 它和下面的這個運算式是等價的:
master^^
你也可以把這些‘標識符‘(spec)疊加起來, 下面這個3個運算式都是指向同一個提交(commit):
master^^^^^^master~3^~2master~6
8.樹對象指標
如果大家對第一章Git物件模型還有印象的話, 就記得提交對象(commit object)是指向一個樹對象(tree object)的. 假如你要得到一個提交對象(commit object)指向的樹對象(tree object)的sha串名, 你就可以在‘樹名‘的後面加上‘{tree}‘來得到它:
master^{tree}
9.二進位標識符
如果你要某個二進位對象(blob)的sha串名,你可以在‘樹名‘(treeish)後添加二進位對象(blob)對應的檔案路徑來得到它。
master:/path/to/file
10.區間
最後, 你可以用".."來指兩個提交(commit)之間的區間. 下面的命令會給出你在"7b593b5" 和"51bea1"之間除了"7b593b5外"的所有提交(commit)(注意:51bea1是最近的提交)。
7b593b5..51bea1
這會包括所有 從 7b593b開始的提交(commit). 譯者注: 相當於 7b593b..HEAD
7b593b..
八、小結
本節是git的中級知識,在添加索引時可以通過配置.gitignore檔案來忽略檔案,又講解了git rebase、git stash和git樹名。
(大資料工程師學習路徑)第三步 Git Community Book----中級技能(上)