簡體   English   中英

如何重置master並將分支保留在git中?

[英]How do I reset master and keep my branch in git?

假如我做

$ git checkout master
$ touch foo.py
$ git commit -m "oops" foo.py
$ git checkout -b new_branch
$ touch bar.py
$ git commit -m "changes" bar.py

現在,當我嘗試推遲對new_branch的更改時,我得到

Local branch 'master' is ahead of remote branch 'origin/master'

如何在不丟失new_branch上的更改(foo.py,bar.py)的同時重置master?

我閱讀了git reset頁面 ,看起來可能涉及--keep,但我不知道。

最初這可能會非常混亂,您需要的是對Git如何實現分支的正確介紹。 但目前我們將使用改造方法。 :-)理解所有這些技巧的竅門是Git的提交是永久的且不變的,但是它的分支(或更確切地說是分支名稱 )是臨時的,實際上實際上是無關緊要的。

在構建新的提交時,有三件事很重要(它們是HEADindexwork-tree ),但是一旦構建並提交了提交,它便是永久性的,很難將Git提交給它。完全失去它。 不過,很容易將其意外放錯位置,因此,我們嘗試避免這種情況。 :-)

如果我們完全忽略分支名稱,則可以繪制存儲庫中存在的提交的圖形 鑒於你做的決策是什么了兩個新的提交,讓我們吸取他們這個樣子,哪里輪o s為承諾,以及AB是兩個的提交:

...--o--o--o
            \
             A
              \
               B

我們可以將它們全部畫在一條線上,但是我想留出空間在右側寫標簽。 提交A是您的“哎呀”,而B是您的“變更”。

有關該圖形繪制的主要注意事項是,每個提交都指向其先前的提交(存儲其哈希ID)。 這意味着提交B指向提交A 提交A指向最近的下一個提交,指向更遠的位置,依此類推。

現在,我們添加標簽- 分支名稱 最后一次無聊的提交o仍可能帶有標簽origin/master 提交A的標簽為master ,提交B的標簽為new_branch ,因此我們將其繪制為:

...--o--o--o   <-- origin/master
            \
             A   <-- master
              \
               B   <-- new_branch (HEAD)

這就是分支名稱為您服務的名稱:它們是提交的指針; 他們會記住每個提交的丑陋哈希ID。

當您在某個分支上並進行提交時,分支名稱隨之出現。 特殊名稱HEAD記住您所在的分支,以便Git知道要移至新提交的名稱。 (至少在masternew_branch短暫地指向commit A時,我們暫時需new_branch )。

你想現在做的是移動master 點到最后的枯燥o提交。 為此,您可以使用git reset ,它允許您以任意方式移動名稱:

git checkout master
git reset --hard origin/master

假設 (請參閱下面的最后部分) origin/master節點確實指向了無聊的o提交的最后一個。 git reset --hard表示: 清除當前索引和工作樹,並根據HEAD移動當前分支,使其指向我在此處命名的提交。 我們必須git checkout master 至上 ,讓HEADmaster 然后git reset這樣做:

...--o--o--o   <-- master (HEAD), origin/master
            \
             A
              \
               B   <-- new_branch

因此,現在僅通過new_branch而不是master可以找到您的兩個新提交AB

(分支名稱還可以為您做幾件事情。特別是,它們可以防止提交被Git的“垃圾收集器”刪除。如果某個提交具有可以找到它的名稱,那么它將受到保護。如果它沒有名稱, ,它不再受保護。有些半隱藏的名稱可以保護所有時間(默認情況下至少為30天),以確保不會意外刪除提交,但是通過這些reflog名稱查找它們很煩人,因此我們盡量不要過分依賴它。

分支名稱也用於git push ,因此它們很重要。)

(我提到“破壞”了上面的索引和工作樹,這並不完全正確git reset命令使用了我們在此處使用的方式,可以完成三個工作:

  • 移動當前分支
  • 重置索引
  • 重置工作樹

它始終執行第一項,可選地添加第二項工作,然后可選地添加第三項工作。 --hard模式執行全部三個操作,-- --mixed模式執行前兩個操作,而--soft模式僅執行一個操作。 為了正確理解它們,我們必須仔細查看索引工作樹的定義,我將其留給其他SO問題/答案。 不過,這里的關鍵項是您希望git reset --hard直到您將所有內容都保存在提交中為止。)

如果沒有origin/master (或者指向太遠)怎么辦?

上面我們假設有一個方便的標簽-所謂的遠程跟蹤分支 -標識了我們要git reset提交的提交, git reset master git reset為指向。 如果沒有該標簽,或者它指向一個更早的提交,則必須以其他方式定位該提交。

有很多方法可以做到這一點。 最簡單的方法是使用其哈希ID。 如果在某個分支上運行git log ,則會看到該分支“上”或“包含在”該分支的每個提交,通常按Git通常的向后順序。 例如,我們可能會git log並看到具有大丑陋哈希ID的提交B ,然后具有其哈希ID的提交A ,然后是具有大丑陋的哈希ID的無聊的提交o

我們可以使用原始哈希ID:

git checkout master && git reset --hard <hash-id>

如果我們沒有標簽。 如果我們有標簽,則可能應該使用它。

您可能還記得使用git log從“ A DOG”獲得幫助:

git log --all --decorate --oneline --graph

A ll使Git顯示所有分支和所有遠程跟蹤分支(以及其他所有內容:標簽,“存儲”,注釋等)。 d ecorate選項將標簽名稱附加到提交。 o neline選項使輸出每次提交僅顯示一行,而g raph選項使Git嘗試繪制提交圖。

如何在不丟失new_branch上的更改(foo.py,bar.py)的同時重置master?

是的,foo.py和bar.py在您的新分支中。

  • 您已經從母版創建了一個分支,但未推送到原點。 因此,當您嘗試推動主機時,您會收到錯誤消息,因為它位於遠程主機之前。

  • 之所以收到該消息,是因為您在本地主機中進行了更改,而沒有將其推送到遠程主機。

您可以通過多種方式“解決”它,通常取決於您的工作流程如何:

  • 在良好的工作流程中,您的master的遠程副本應該是好的副本,而您的master的本地副本只是遠程副本的副本。 使用此工作流程,您將永遠不會再收到此消息。

  • 如果您以其他方式工作並且應該推送本地更改,則只需使用git push origin即可,前提是origin是您的遠程主機

我將如何做:

git checkout master
git create -b la_lalalla
touch foo.py bar.py
git add drama.py bar.py
git commit -m "Drama commit"

將分支合並到主節點,這取決於您進行合並或變基,然后,

git push origin master. 

您完成了將兩個文件添加到原點/原版的操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM