<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      git rebase 更改歷史樹

      來源:http://github.danmarner.com/section/ch6-4/

      重寫歷史

      很多時候,在 Git 上工作的時候,你也許會由于某種原因想要修訂你的提交歷史。Git 的一個卓越之處就是它允許你在最后可能的時刻再作決定。你可以在你即將提交暫存區時決定什么文件歸入哪一次提交,你可以使用 stash 命令來決定你暫時擱置的工作,你可以重寫已經發生的提交以使它們看起來是另外一種樣子。這個包括改變提交的次序、改變說明或者修改提交中包含的文件,將提交歸并、拆分或者完全刪除——這一切在你尚未開始將你的工作和別人共享前都是可以的。

      在這一節中,你會學到如何完成這些很有用的任務以使你的提交歷史在你將其共享給別人之前變成你想要的樣子。

      改變最近一次提交

      改變最近一次提交也許是最常見的重寫歷史的行為。對于你的最近一次提交,你經常想做兩件基本事情:改變提交說明,或者改變你剛剛通過增加,改變,刪除而記錄的快照。

      如果你只想修改最近一次提交說明,這非常簡單:

      $ git commit --amend
      

      這會把你帶入文本編輯器,里面包含了你最近一次提交說明,供你修改。當你保存并退出編輯器,這個編輯器會寫入一個新的提交,里面包含了那個說明,并且讓它成為你的新的最近一次提交。

      如果你完成提交后又想修改被提交的快照,增加或者修改其中的文件,可能因為你最初提交時,忘了添加一個新建的文件,這個過程基本上一樣。你通過修改文件然后對其運行git add或對一個已被記錄的文件運行git rm,隨后的git commit --amend會獲取你當前的暫存區并將它作為新提交對應的快照。

      使用這項技術的時候你必須小心,因為修正會改變提交的SHA-1值。這個很像是一次非常小的rebase——不要在你最近一次提交被推送后還去修正它。

      修改多個提交說明

      要修改歷史中更早的提交,你必須采用更復雜的工具。Git沒有一個修改歷史的工具,但是你可以使用rebase工具來衍合一系列的提交到它們原來所在的HEAD上而不是移到新的上。依靠這個交互式的rebase工具,你就可以停留在每一次提交后,如果你想修改或改變說明、增加文件或任何其他事情。你可以通過給git rebase增加-i選項來以交互方式地運行rebase。你必須通過告訴命令衍合到哪次提交,來指明你需要重寫的提交的回溯深度。

      例如,你想修改最近三次的提交說明,或者其中任意一次,你必須給git rebase -i提供一個參數,指明你想要修改的提交的父提交,例如HEAD~2或者HEAD~3??赡苡涀?code>~3更加容易,因為你想修改最近三次提交;但是請記住你事實上所指的是四次提交之前,即你想修改的提交的父提交。

      $ git rebase -i HEAD~3
      

      再次提醒這是一個衍合命令——HEAD~3..HEAD范圍內的每一次提交都會被重寫,無論你是否修改說明。不要涵蓋你已經推送到中心服務器的提交——這么做會使其他開發者產生混亂,因為你提供了同樣變更的不同版本。

      運行這個命令會為你的文本編輯器提供一個提交列表,看起來像下面這樣

      pick f7f3f6d changed my name a bit
      pick 310154e updated README formatting and added blame
      pick a5f4a0d added cat-file
      
      # Rebase 710f0f8..a5f4a0d onto 710f0f8
      #
      # Commands:
      #  p, pick = use commit
      #  e, edit = use commit, but stop for amending
      #  s, squash = use commit, but meld into previous commit
      #
      # If you remove a line here THAT COMMIT WILL BE LOST.
      # However, if you remove everything, the rebase will be aborted.
      #
      

      很重要的一點是你得注意這些提交的順序與你通常通過log命令看到的是相反的。如果你運行log,你會看到下面這樣的結果:

      $ git log --pretty=format:"%h %s" HEAD~3..HEAD
      a5f4a0d added cat-file
      310154e updated README formatting and added blame
      f7f3f6d changed my name a bit
      

      請注意這里的倒序。交互式的rebase給了你一個即將運行的腳本。它會從你在命令行上指明的提交開始(HEAD~3)然后自上至下重播每次提交里引入的變更。它將最早的列在頂上而不是最近的,因為這是第一個需要重播的。

      你需要修改這個腳本來讓它停留在你想修改的變更上。要做到這一點,你只要將你想修改的每一次提交前面的pick改為edit。例如,只想修改第三次提交說明的話,你就像下面這樣修改文件:

      edit f7f3f6d changed my name a bit
      pick 310154e updated README formatting and added blame
      pick a5f4a0d added cat-file
      

      當你保存并退出編輯器,Git會倒回至列表中的最后一次提交,然后把你送到命令行中,同時顯示以下信息:

      $ git rebase -i HEAD~3
      Stopped at 7482e0d... updated the gemspec to hopefully work better
      You can amend the commit now, with
      
             git commit --amend
      
      Once you’re satisfied with your changes, run
      
             git rebase --continue
      

      這些指示很明確地告訴了你該干什么。輸入

      $ git commit --amend
      

      修改提交說明,退出編輯器。然后,運行

      $ git rebase --continue
      

      這個命令會自動應用其他兩次提交,你就完成任務了。如果你將更多行的 pick 改為 edit ,你就能對你想修改的提交重復這些步驟。Git每次都會停下,讓你修正提交,完成后繼續運行。

      重排提交

      你也可以使用交互式的衍合來徹底重排或刪除提交。如果你想刪除"added cat-file"這個提交并且修改其他兩次提交引入的順序,你將rebase腳本從這個

      pick f7f3f6d changed my name a bit
      pick 310154e updated README formatting and added blame
      pick a5f4a0d added cat-file
      

      改為這個:

      pick 310154e updated README formatting and added blame
      pick f7f3f6d changed my name a bit
      

      當你保存并退出編輯器,Git 將分支倒回至這些提交的父提交,應用310154e,然后f7f3f6d,接著停止。你有效地修改了這些提交的順序并且徹底刪除了"added cat-file"這次提交。

      壓制(Squashing)提交

      交互式的衍合工具還可以將一系列提交壓制為單一提交。腳本在 rebase 的信息里放了一些有用的指示:

      #
      # Commands:
      #  p, pick = use commit
      #  e, edit = use commit, but stop for amending
      #  s, squash = use commit, but meld into previous commit
      #
      # If you remove a line here THAT COMMIT WILL BE LOST.
      # However, if you remove everything, the rebase will be aborted.
      #
      

      如果不用"pick"或者"edit",而是指定"squash",Git 會同時應用那個變更和它之前的變更并將提交說明歸并。因此,如果你想將這三個提交合并為單一提交,你可以將腳本修改成這樣:

      pick f7f3f6d changed my name a bit
      squash 310154e updated README formatting and added blame
      squash a5f4a0d added cat-file
      

      當你保存并退出編輯器,Git 會應用全部三次變更然后將你送回編輯器來歸并三次提交說明。

      # This is a combination of 3 commits.
      # The first commit's message is:
      changed my name a bit
      
      # This is the 2nd commit message:
      
      updated README formatting and added blame
      
      # This is the 3rd commit message:
      
      added cat-file
      

      當你保存之后,你就擁有了一個包含前三次提交的全部變更的單一提交。

      拆分提交

      拆分提交就是撤銷一次提交,然后多次部分地暫存或提交直到結束。例如,假設你想將三次提交中的中間一次拆分。將"updated README formatting and added blame"拆分成兩次提交:第一次為"updated README formatting",第二次為"added blame"。你可以在rebase -i腳本中修改你想拆分的提交前的指令為"edit":

      pick f7f3f6d changed my name a bit
      edit 310154e updated README formatting and added blame
      pick a5f4a0d added cat-file
      

      然后,這個腳本就將你帶入命令行,你重置那次提交,提取被重置的變更,從中創建多次提交。當你保存并退出編輯器,Git 倒回到列表中第一次提交的父提交,應用第一次提交(f7f3f6d),應用第二次提交(310154e),然后將你帶到控制臺。那里你可以用git reset HEAD^對那次提交進行一次混合的重置,這將撤銷那次提交并且將修改的文件撤回。此時你可以暫存并提交文件,直到你擁有多次提交,結束后,運行git rebase --continue。

      $ git reset HEAD^
      $ git add README
      $ git commit -m 'updated README formatting'
      $ git add lib/simplegit.rb
      $ git commit -m 'added blame'
      $ git rebase --continue
      

      Git在腳本中應用了最后一次提交(a5f4a0d),你的歷史看起來就像這樣了:

      $ git log -4 --pretty=format:"%h %s"
      1c002dd added cat-file
      9b29157 added blame
      35cfb2b updated README formatting
      f3cc40e changed my name a bit
      

      再次提醒,這會修改你列表中的提交的 SHA 值,所以請確保這個列表里不包含你已經推送到共享倉庫的提交。

      核彈級選項: filter-branch

      如果你想用腳本的方式修改大量的提交,還有一個重寫歷史的選項可以用——例如,全局性地修改電子郵件地址或者將一個文件從所有提交中刪除。這個命令是filter-branch,這個會大面積地修改你的歷史,所以你很有可能不該去用它,除非你的項目尚未公開,沒有其他人在你準備修改的提交的基礎上工作。盡管如此,這個可以非常有用。你會學習一些常見用法,借此對它的能力有所認識。

      從所有提交中刪除一個文件

      這個經常發生。有些人不經思考使用git add .,意外地提交了一個巨大的二進制文件,你想將它從所有地方刪除。也許你不小心提交了一個包含密碼的文件,而你想讓你的項目開源。filter-branch大概會是你用來清理整個歷史的工具。要從整個歷史中刪除一個名叫password.txt的文件,你可以在filter-branch上使用--tree-filter選項:

      $ git filter-branch --tree-filter 'rm -f passwords.txt' HEAD
      Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21)
      Ref 'refs/heads/master' was rewritten
      

      --tree-filter選項會在每次檢出項目時先執行指定的命令然后重新提交結果。在這個例子中,你會在所有快照中刪除一個名叫 password.txt 的文件,無論它是否存在。如果你想刪除所有不小心提交上去的編輯器備份文件,你可以運行類似git filter-branch --tree-filter 'rm -f *~' HEAD的命令。

      你可以觀察到 Git 重寫目錄樹并且提交,然后將分支指針移到末尾。一個比較好的辦法是在一個測試分支上做這些然后在你確定產物真的是你所要的之后,再 hard-reset 你的主分支。要在你所有的分支上運行filter-branch的話,你可以傳遞一個--all給命令。

      將一個子目錄設置為新的根目錄

      假設你完成了從另外一個代碼控制系統的導入工作,得到了一些沒有意義的子目錄(trunk, tags等等)。如果你想讓trunk子目錄成為每一次提交的新的項目根目錄,filter-branch也可以幫你做到:

      $ git filter-branch --subdirectory-filter trunk HEAD
      Rewrite 856f0bf61e41a27326cdae8f09fe708d679f596f (12/12)
      Ref 'refs/heads/master' was rewritten
      

      現在你的項目根目錄就是trunk子目錄了。Git 會自動地刪除不對這個子目錄產生影響的提交。

      全局性地更換電子郵件地址

      另一個常見的案例是你在開始時忘了運行git config來設置你的姓名和電子郵件地址,也許你想開源一個項目,把你所有的工作電子郵件地址修改為個人地址。無論哪種情況你都可以用filter-branch來更換多次提交里的電子郵件地址。你必須小心一些,只改變屬于你的電子郵件地址,所以你使用--commit-filter

      $ git filter-branch --commit-filter '
              if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ];
              then
                      GIT_AUTHOR_NAME="Scott Chacon";
                      GIT_AUTHOR_EMAIL="schacon@example.com";
                      git commit-tree "$@";
              else
                      git commit-tree "$@";
              fi' HEAD
      

      這個會遍歷并重寫所有提交使之擁有你的新地址。因為提交里包含了它們的父提交的SHA-1值,這個命令會修改你的歷史中的所有提交,而不僅僅是包含了匹配的電子郵件地址的那些。

      posted on 2012-06-24 00:28  大寶pku  閱讀(6397)  評論(0)    收藏  舉報

      導航

      主站蜘蛛池模板: 婷婷久久香蕉五月综合加勒比| 欧美成人www免费全部网站| 亚洲国产精品一二三区| 国产毛片基地| 久久精品av国产一区二区| 亚洲综合黄色的在线观看| 国产麻豆精品av在线观看| 中文字幕人妻不卡精品| 亚洲中文字幕av天堂| 亚洲国产成人片在线观看无码| 久久老熟妇精品免费观看| 亚洲av永久无码精品天堂久久| 26uuu另类亚洲欧美日本| 熟女人妻精品一区二区视频| 色婷婷婷丁香亚洲综合| 亚洲精品一区三区三区在| 日韩av一区二区三区不卡| 日韩免费无码视频一区二区三区| 铅山县| 精品国产成人午夜福利| 欧美成本人视频免费播放| 久青草视频在线免费观看| 久章草在线精品视频免费观看| 18禁免费无码无遮挡不卡网站| 无码人妻精品一区二区三区东京热| 免费国产一级特黄aa大片在线| 国产精品成人高潮av| 精品人妻日韩中文字幕| 自拍偷在线精品自拍偷免费| aa性欧美老妇人牲交免费| 亚洲国产大胸一区二区三区| 国产精品福利自产拍在线观看| 亚洲av无码精品色午夜蛋壳| 日本一卡2卡3卡四卡精品网站| 永久免费AV无码网站YY| 国产无遮挡猛进猛出免费软件| 久久月本道色综合久久| 精品久久久久久无码人妻蜜桃| 加勒比无码人妻东京热| 亚洲av影院一区二区三区| 亚洲日本乱码在线观看|