[英]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的提交是永久的且不變的,但是它的分支(或更確切地說是分支名稱 )是臨時的,實際上實際上是無關緊要的。
在構建新的提交時,有三件事很重要(它們是HEAD
, index和work-tree ),但是一旦構建並提交了提交,它便是永久性的,很難將Git提交給它。完全失去它。 不過,很容易將其意外放錯位置,因此,我們嘗試避免這種情況。 :-)
如果我們完全忽略分支名稱,則可以繪制存儲庫中存在的提交的圖形 。 鑒於你做的決策是什么了兩個新的提交,讓我們吸取他們這個樣子,哪里輪o
s為承諾,以及A
和B
是兩個新的提交:
...--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知道要移至新提交的名稱。 (至少在master
和new_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
至上 ,讓HEAD
名master
。 然后git reset
這樣做:
...--o--o--o <-- master (HEAD), origin/master
\
A
\
B <-- new_branch
因此,現在僅通過new_branch
而不是master
可以找到您的兩個新提交A
和B
(分支名稱還可以為您做幾件事情。特別是,它們可以防止提交被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.