91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么用Git變基來改變歷史

發布時間:2021-10-25 10:43:57 來源:億速云 閱讀:120 作者:小新 欄目:系統運維

這篇文章給大家分享的是有關怎么用Git變基來改變歷史的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

Git  核心的附加價值之一就是編輯歷史記錄的能力。與將歷史記錄視為神圣的記錄的版本控制系統不同,在 Git  中,我們可以修改歷史記錄以適應我們的需要。這為我們提供了很多強大的工具,讓我們可以像使用重構來維護良好的軟件設計實踐一樣,編織良好的提交歷史。這些工具對于新手甚至是有經驗的  Git 用戶來說可能會有些令人生畏,但本指南將幫助我們揭開強大的 git-rebase 的神秘面紗。

值得注意的是:一般建議不要修改公共分支、共享分支或穩定分支的歷史記錄。編輯特性分支和個人分支的歷史記錄是可以的,編輯還沒有推送的提交也是可以的。在編輯完提交后,可以使用 git push -f 來強制推送你的修改到個人分支或特性分支。

盡管有這么可怕的警告,但值得一提的是,本指南中提到的一切都是非破壞性操作。實際上,在 Git 中永久丟失數據是相當困難的。本指南結尾介紹了在犯錯誤時進行糾正的方法。

設置沙盒

我們不想破壞你的任何實際的版本庫,所以在整個指南中,我們將使用一個沙盒版本庫。運行這些命令來開始工作。1

git init /tmp/rebase-sandboxcd /tmp/rebase-sandboxgit commit --allow-empty -m"Initial commit"

如果你遇到麻煩,只需運行 rm -rf /tmp/rebase-sandbox,并重新運行這些步驟即可重新開始。本指南的每一步都可以在新的沙箱上運行,所以沒有必要重做每個任務。

修正最近的提交

讓我們從簡單的事情開始:修復你最近的提交。讓我們向沙盒中添加一個文件,并犯個錯誤。

echo "Hello wrold!" >greeting.txtgit add greeting.txtgit commit -m"Add greeting.txt"

修復這個錯誤是非常容易的。我們只需要編輯文件,然后用 --amend 提交就可以了,就像這樣:

echo "Hello world!" >greeting.txtgit commit -a --amend

指定 -a 會自動將所有 Git 已經知道的文件進行暫存(例如 Git 添加的),而 --amend 會將更改的內容壓扁到最近的提交中。保存并退出你的編輯器(如果需要,你現在可以修改提交信息)。你可以通過運行 git show 看到修復的提交。

commit f5f19fbf6d35b2db37dcac3a55289ff9602e4d00 (HEAD -> master)Author: Drew DeVault Date:   Sun Apr 28 11:09:47 2019 -0400     Add greeting.txt diff --git a/greeting.txt b/greeting.txtnew file mode 100644index 0000000..cd08755--- /dev/null+++ b/greeting.txt@@ -0,0 +1 @@+Hello world!

修復較舊的提交

--amend 僅適用于最近的提交。如果你需要修正一個較舊的提交會怎么樣?讓我們從相應地設置沙盒開始:

echo "Hello!" >greeting.txtgit add greeting.txtgit commit -m"Add greeting.txt" echo "Goodbye world!" >farewell.txtgit add farewell.txtgit commit -m"Add farewell.txt"

看起來 greeting.txt 像是丟失了 "world"。讓我們正常地寫個提交來解決這個問題:

echo "Hello world!" >greeting.txtgit commit -a -m"fixup greeting.txt"

現在文件看起來正確,但是我們的歷史記錄可以更好一點 —— 讓我們使用新的提交來“修復”(fixup)最后一個提交。為此,我們需要引入一個新工具:交互式變基。我們將以這種方式編輯最后三個提交,因此我們將運行 git rebase -i HEAD~3-i 代表交互式)。這樣會打開文本編輯器,如下所示:

pick 8d3fc77 Add greeting.txtpick 2a73a77 Add farewell.txtpick 0b9d0bb fixup greeting.txt # Rebase f5f19fb..0b9d0bb onto f5f19fb (3 commands)## Commands:# p, pick <commit> = use commit# f, fixup <commit> = like "squash", but discard this commit's log message

這是變基計劃,通過編輯此文件,你可以指導 Git 如何編輯歷史記錄。我已經將該摘要削減為僅與變基計劃這一部分相關的細節,但是你可以在文本編輯器中瀏覽完整的摘要。

當我們保存并關閉編輯器時,Git 將從其歷史記錄中刪除所有這些提交,然后一次執行一行。默認情況下,它將選取(pick)每個提交,將其從堆中召喚出來并添加到分支中。如果我們對此文件根本沒有做任何編輯,則將直接回到起點,按原樣選取每個提交。現在,我們將使用我最喜歡的功能之一:修復(fixup)。編輯第三行,將操作從 pick 更改為 fixup,并將其立即移至我們要“修復”的提交之后:

pick 8d3fc77 Add greeting.txtfixup 0b9d0bb fixup greeting.txtpick 2a73a77 Add farewell.txt

技巧:我們也可以只用 f 來縮寫它,以加快下次的速度。

保存并退出編輯器,Git 將運行這些命令。我們可以檢查日志以驗證結果:

$ git log -2 --onelinefcff6ae (HEAD -> master) Add farewell.txta479e94 Add greeting.txt

將多個提交壓扁為一個

在工作時,當你達到較小的里程碑或修復以前的提交中的錯誤時,你可能會發現寫很多提交很有用。但是,在將你的工作合并到 master 分支之前,將這些提交“壓扁”(squash)到一起以使歷史記錄更清晰可能很有用。為此,我們將使用“壓扁”(squash)操作。讓我們從編寫一堆提交開始,如果要加快速度,只需復制并粘貼這些:

git checkout -b squashfor c in H e l l o , ' ' w o r l d; do    echo "$c" >>squash.txt    git add squash.txt    git commit -m"Add '$c' to squash.txt"done

要制作出一個寫著 “Hello,world” 的文件,要做很多事情!讓我們開始另一個交互式變基,將它們壓扁在一起。請注意,我們首先簽出了一個分支來進行嘗試。因此,因為我們使用 git rebase -i master 進行的分支,我們可以快速變基所有提交。結果:

pick 1e85199 Add 'H' to squash.txtpick fff6631 Add 'e' to squash.txtpick b354c74 Add 'l' to squash.txtpick 04aaf74 Add 'l' to squash.txtpick 9b0f720 Add 'o' to squash.txtpick 66b114d Add ',' to squash.txtpick dc158cd Add ' ' to squash.txtpick dfcf9d6 Add 'w' to squash.txtpick 7a85f34 Add 'o' to squash.txtpick c275c27 Add 'r' to squash.txtpick a513fd1 Add 'l' to squash.txtpick 6b608ae Add 'd' to squash.txt # Rebase 1af1b46..6b608ae onto 1af1b46 (12 commands)## Commands:# p, pick <commit> = use commit# s, squash <commit> = use commit, but meld into previous commit

技巧:你的本地 master 分支獨立于遠程 master 分支而發展,并且 Git 將遠程分支存儲為 origin/master。結合這種技巧,git rebase -i origin/master 通常是一種非常方便的方法,可以變基所有尚未合并到上游的提交!

我們將把所有這些更改壓扁到第一個提交中。為此,將第一行除外的每個“選取”(pick)操作都更改為“壓扁”(squash),如下所示:

pick 1e85199 Add 'H' to squash.txtsquash fff6631 Add 'e' to squash.txtsquash b354c74 Add 'l' to squash.txtsquash 04aaf74 Add 'l' to squash.txtsquash 9b0f720 Add 'o' to squash.txtsquash 66b114d Add ',' to squash.txtsquash dc158cd Add ' ' to squash.txtsquash dfcf9d6 Add 'w' to squash.txtsquash 7a85f34 Add 'o' to squash.txtsquash c275c27 Add 'r' to squash.txtsquash a513fd1 Add 'l' to squash.txtsquash 6b608ae Add 'd' to squash.txt

保存并關閉編輯器時,Git 會考慮片刻,然后再次打開編輯器以修改最終的提交消息。你會看到以下內容:

# This is a combination of 12 commits.# This is the 1st commit message: Add 'H' to squash.txt # This is the commit message #2: Add 'e' to squash.txt # This is the commit message #3: Add 'l' to squash.txt # This is the commit message #4: Add 'l' to squash.txt # This is the commit message #5: Add 'o' to squash.txt # This is the commit message #6: Add ',' to squash.txt # This is the commit message #7: Add ' ' to squash.txt # This is the commit message #8: Add 'w' to squash.txt # This is the commit message #9: Add 'o' to squash.txt # This is the commit message #10: Add 'r' to squash.txt # This is the commit message #11: Add 'l' to squash.txt # This is the commit message #12: Add 'd' to squash.txt # Please enter the commit message for your changes. Lines starting# with '#' will be ignored, and an empty message aborts the commit.## Date:      Sun Apr 28 14:21:56 2019 -0400## interactive rebase in progress; onto 1af1b46# Last commands done (12 commands done):#    squash a513fd1 Add 'l' to squash.txt#    squash 6b608ae Add 'd' to squash.txt# No commands remaining.# You are currently rebasing branch 'squash' on '1af1b46'.## Changes to be committed:#   new file:   squash.txt#

默認情況下,這是所有要壓扁的提交的消息的組合,但是像這樣將其保留肯定不是你想要的。不過,舊的提交消息在編寫新的提交消息時可能很有用,所以放在這里以供參考。

提示:你在上一節中了解的“修復”(fixup)命令也可以用于此目的,但它會丟棄壓扁的提交的消息。

讓我們刪除所有內容,并用更好的提交消息替換它,如下所示:

Add squash.txt with contents "Hello, world" # Please enter the commit message for your changes. Lines starting# with '#' will be ignored, and an empty message aborts the commit.## Date:      Sun Apr 28 14:21:56 2019 -0400## interactive rebase in progress; onto 1af1b46# Last commands done (12 commands done):#    squash a513fd1 Add 'l' to squash.txt#    squash 6b608ae Add 'd' to squash.txt# No commands remaining.# You are currently rebasing branch 'squash' on '1af1b46'.## Changes to be committed:#   new file:   squash.txt#

保存并退出編輯器,然后檢查你的 Git 日志,成功!

commit c785f476c7dff76f21ce2cad7c51cf2af00a44b6 (HEAD -> squash)Author: Drew DeVaultDate:   Sun Apr 28 14:21:56 2019 -0400     Add squash.txt with contents "Hello, world"

在繼續之前,讓我們將所做的更改拉入 master 分支中,并擺脫掉這一草稿。我們可以像使用 git merge 一樣使用 git rebase,但是它避免了創建合并提交:

git checkout mastergit rebase squashgit branch -D squash

除非我們實際上正在合并無關的歷史記錄,否則我們通常希望避免使用 git merge。如果你有兩個不同的分支,則 git merge 對于記錄它們合并的時間非常有用。在正常工作過程中,變基通常更為合適。

將一個提交拆分為多個

有時會發生相反的問題:一個提交太大了。讓我們來看一看拆分它們。這次,讓我們寫一些實際的代碼。從一個簡單的 C 程序 2 開始(你仍然可以將此代碼段復制并粘貼到你的 shell 中以快速執行此操作):

cat <<EOF >main.cint main(int argc, char *argv[]) {    return 0;}EOF

首先提交它:

git add main.cgit commit -m"Add C program skeleton"

然后把這個程序擴展一些:

cat <<EOF >main.c#include &ltstdio.h> const char *get_name() {    static char buf[128];    scanf("%s", buf);    return buf;} int main(int argc, char *argv[]) {    printf("What's your name? ");    const char *name = get_name();    printf("Hello, %s!\n", name);    return 0;}EOF

提交之后,我們就可以準備學習如何將其拆分:

git commit -a -m"Flesh out C program"

第一步是啟動交互式變基。讓我們用 git rebase -i HEAD~2 來變基這兩個提交,給出的變基計劃如下:

pick 237b246 Add C program skeletonpick b3f188b Flesh out C program # Rebase c785f47..b3f188b onto c785f47 (2 commands)## Commands:# p, pick <commit> = use commit# e, edit <commit> = use commit, but stop for amending

將第二個提交的命令從 pick 更改為 edit,然后保存并關閉編輯器。Git 會考慮一秒鐘,然后向你建議:

Stopped at b3f188b...  Flesh out C programYou can amend the commit now, with   git commit --amend Once you are satisfied with your changes, run   git rebase --continue

我們可以按照以下說明為提交添加新的更改,但我們可以通過運行 git reset HEAD^ 來進行“軟重置” 3。如果在此之后運行 git status,你將看到它取消了提交最新的提交,并將其更改添加到工作樹中:

Last commands done (2 commands done):   pick 237b246 Add C program skeleton   edit b3f188b Flesh out C programNo commands remaining.You are currently splitting a commit while rebasing branch 'master' on 'c785f47'.  (Once your working directory is clean, run "git rebase --continue") Changes not staged for commit:  (use "git add ..." to update what will be committed)  (use "git checkout -- ..." to discard changes in working directory)   modified:   main.c no changes added to commit (use "git add" and/or "git commit -a")

為了對此進行拆分,我們將進行交互式提交。這使我們能夠選擇性地僅提交工作樹中的特定更改。運行 git commit -p 開始此過程,你將看到以下提示:

diff --git a/main.c b/main.cindex b1d9c2c..3463610 100644--- a/main.c+++ b/main.c@@ -1,3 +1,14 @@+#include &ltstdio.h>++const char *get_name() {+    static char buf[128];+    scanf("%s", buf);+    return buf;+}+ int main(int argc, char *argv[]) {+    printf("What's your name? ");+    const char *name = get_name();+    printf("Hello, %s!\n", name);     return 0; }Stage this hunk [y,n,q,a,d,s,e,?]?

Git 僅向你提供了一個“大塊”(即單個更改)以進行提交。不過,這太大了,讓我們使用 s 命令將這個“大塊”拆分成較小的部分。

Split into 2 hunks.@@ -1 +1,9 @@+#include <stdio.h>++const char *get_name() {+    static char buf[128];+    scanf("%s", buf);+    return buf;+}+ int main(int argc, char *argv[]) {Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]?

提示:如果你對其他選項感到好奇,請按 ? 匯總顯示。

這個大塊看起來更好:單一、獨立的更改。讓我們按 y 來回答問題(并暫存那個“大塊”),然后按 q 以“退出”交互式會話并繼續進行提交。會彈出編輯器,要求輸入合適的提交消息。

Add get_name function to C program # Please enter the commit message for your changes. Lines starting# with '#' will be ignored, and an empty message aborts the commit.## interactive rebase in progress; onto c785f47# Last commands done (2 commands done):#    pick 237b246 Add C program skeleton#    edit b3f188b Flesh out C program# No commands remaining.# You are currently splitting a commit while rebasing branch 'master' on 'c785f47'.## Changes to be committed:#   modified:   main.c## Changes not staged for commit:#   modified:   main.c#

保存并關閉編輯器,然后我們進行第二次提交。我們可以執行另一次交互式提交,但是由于我們只想在此提交中包括其余更改,因此我們將執行以下操作:

git commit -a -m"Prompt user for their name"git rebase --continue

最后一條命令告訴 Git 我們已經完成了此提交的編輯,并繼續執行下一個變基命令。這樣就行了!運行 git log 來查看你的勞動成果:

$ git log -3 --onelinefe19cc3 (HEAD -> master) Prompt user for their name659a489 Add get_name function to C program237b246 Add C program skeleton

重新排序提交

這很簡單。讓我們從設置沙箱開始:

echo "Goodbye now!" >farewell.txtgit add farewell.txtgit commit -m"Add farewell.txt" echo "Hello there!" >greeting.txtgit add greeting.txtgit commit -m"Add greeting.txt" echo "How're you doing?" >inquiry.txtgit add inquiry.txtgit commit -m"Add inquiry.txt"

現在 git log 看起來應如下所示:

f03baa5 (HEAD -> master) Add inquiry.txta4cebf7 Add greeting.txt90bb015 Add farewell.txt

顯然,這都是亂序。讓我們對過去的 3 個提交進行交互式變基來解決此問題。運行 git rebase -i HEAD~3,這個變基規劃將出現:

pick 90bb015 Add farewell.txtpick a4cebf7 Add greeting.txtpick f03baa5 Add inquiry.txt # Rebase fe19cc3..f03baa5 onto fe19cc3 (3 commands)## Commands:# p, pick <commit> = use commit## These lines can be re-ordered; they are executed from top to bottom.

現在,解決方法很簡單:只需按照你希望提交出現的順序重新排列這些行。應該看起來像這樣:

pick a4cebf7 Add greeting.txtpick f03baa5 Add inquiry.txtpick 90bb015 Add farewell.txt

保存并關閉你的編輯器,而 Git 將為你完成其余工作。請注意,在實踐中這樣做可能會導致沖突,參看下面章節以獲取解決沖突的幫助。

git pull &ndash;rebase

如果你一直在由上游更新的分支 <branch>(比如說原始遠程)上做一些提交,通常 git pull 會創建一個合并提交。在這方面,git pull 的默認行為等同于:

git fetch origin <branch>git merge origin/<branch>

假設本地分支 <branch> 配置為從原始遠程跟蹤 <branch> 分支,即:

$ git config branch.<branch>.remoteorigin$ git config branch.<branch>.mergerefs/heads/<branch>

還有另一種選擇,它通常更有用,并且會讓歷史記錄更清晰:git pull --rebase。與合并方式不同,這基本上 4 等效于以下內容:

git fetch origingit rebase origin/<branch>

合并方式更簡單易懂,但是如果你了解如何使用 git rebase,那么變基方式幾乎可以做到你想要做的任何事情。如果愿意,可以將其設置為默認行為,如下所示:

git config --global pull.rebase true

當你執行此操作時,從技術上講,你在應用我們在下一節中討論的過程&hellip;&hellip;因此,讓我們也解釋一下故意執行此操作的含義。

使用 git rebase 來變基

具有諷刺意味的是,我最少使用的 Git 變基功能是它以之命名的功能:變基分支。假設你有以下分支:

A--B--C--D--> master   \--E--F--> feature-1      \--G--> feature-2

事實證明,feature-2 不依賴于 feature-1 的任何更改,它依賴于提交 E,因此你可以將其作為基礎脫離 master。因此,解決方法是:

git rebase --onto master feature-1 feature-2

非交互式變基對所有牽連的提交都執行默認操作(pick5 ,它只是簡單地將不在 feature-1 中的 feature-2 中提交重放到 master 上。你的歷史記錄現在看起來像這樣:

A--B--C--D--> master   |     \--G--> feature-2   \--E--F--> feature-1

解決沖突

解決合并沖突的詳細信息不在本指南的范圍內,將來請你注意另一篇指南。假設你熟悉通常的解決沖突的方法,那么這里是專門適用于變基的部分。

有時,在進行變基時會遇到合并沖突,你可以像處理其他任何合并沖突一樣處理該沖突。Git 將在受影響的文件中設置沖突標記,git status 將顯示你需要解決的問題,并且你可以使用 git addgit rm 將文件標記為已解決。但是,在 git rebase 的上下文中,你應該注意兩個選項。

首先是如何完成沖突解決。解決由于 git merge 引起的沖突時,與其使用 git commit 那樣的命令,更適當的變基命令是 git rebase --continue。但是,還有一個可用的選項:git rebase --skip。 這將跳過你正在處理的提交,它不會包含在變基中。這在執行非交互性變基時最常見,這時 Git 不會意識到它從“其他”分支中提取的提交是與“我們”分支上沖突的提交的更新版本。

幫幫我! 我把它弄壞了!

毫無疑問,變基有時會很難。如果你犯了一個錯誤,并因此而丟失了所需的提交,那么可以使用 git reflog 來節省下一天的時間。運行此命令將向你顯示更改一個引用(即分支和標記)的每個操作。每行顯示你的舊引用所指向的內容,你可對你認為丟失的 Git 提交執行 git cherry-pickgit checkoutgit show 或任何其他操作。


  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. 我們添加了一個空的初始提交以簡化本教程的其余部分,因為要對版本庫的初始提交進行變基需要特殊的命令(即git rebase --root)。  ?

  3. 如果要編譯此程序,請運行 cc -o main main.c,然后運行 ./main 查看結果。 ?

  4. 實際上,這是“混合重置”。“軟重置”(使用 git reset --soft 完成)將暫存更改,因此你無需再次 git add 添加它們,并且可以一次性提交所有更改。這不是我們想要的。我們希望選擇性地暫存部分更改,以拆分提交。 ?

  5. 實際上,這取決于上游分支本身是否已變基或刪除/壓扁了某些提交。git pull --rebase 嘗試通過在 git rebasegit merge-base 中使用 “復刻點fork-point” 機制來從這種情況中恢復,以避免變基非本地提交。 ?

  6. 實際上,這取決于 Git 的版本。直到 2.26.0 版,默認的非交互行為以前與交互行為稍有不同,這種方式通常并不重要。  ?

感謝各位的閱讀!關于“怎么用Git變基來改變歷史”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

git
AI

班玛县| 武清区| 临夏县| 铜川市| 达拉特旗| 微博| 合水县| 淮滨县| 如皋市| 旅游| 珠海市| 东城区| 甘孜县| 巴彦淖尔市| 大兴区| 瓦房店市| 达州市| 土默特右旗| 沐川县| 万全县| 五台县| 南昌市| 潮安县| 天等县| 枣阳市| 连城县| 萍乡市| 高淳县| 兴安盟| 化德县| 武胜县| 安吉县| 乳源| 天柱县| 东阳市| 桃园县| 桂林市| 七台河市| 通渭县| 宿松县| 凌云县|