簡體   English   中英

Git:如何用上一個提交而不是分支或git revert替換當前的工作目錄?

[英]Git: How do you replace your current working directory with a previous commit without branching or git revert?

有什么簡單的方法可以使用git嗎?

提交復制粘貼圖

基本上,我想在提交歷史記錄的頂部創建一個新的提交,它等同於歷史記錄中的先前提交(例如,將項目還原到先前的狀態)。

我不想使用分支,因為我正在向從未使用過git的人講授此內容,並且我想使事情盡可能“線性”。 (我的大多數聽眾只需要備份內容,查看項目歷史記錄,並在必要時將項目還原到以前的狀態即可,但沒有別的選擇。)

我不想使用git revert --no-commit 49a732c..HEAD因為如果49a732c之后確實發生合並,這會給出錯誤消息(我承認我的聽眾不太可能,但是有時確實會發生使錯誤消息消失的瘋狂嘗試)。

我也不想刪除/重寫歷史記錄。

本質上,有沒有更簡單的方法可以做到這一點?

# make sure on master and working directory clean
me@laptop:~/Desktop/proj$ git status
On branch master
nothing to commit, working directory clean

# check out commit to restore
me@laptop:~/Desktop/proj$ git checkout 49a732c
Note: checking out '49a732c'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at 49a732c... Fix bugs.

# copy project checked out at 49a732c to temp folder
me@laptop:~/Desktop/proj$ cp -r . ../temp

# check out master again
me@laptop:~/Desktop/proj$ git checkout master
Previous HEAD position was 49a732c... Fix bugs.
Switched to branch 'master'

# remove everything except .git
me@laptop:~/Desktop/proj$ rm -rfv !(".git")
rm: refusing to remove '.' or '..' directory: skipping '.'
rm: refusing to remove '.' or '..' directory: skipping '..'
removed 'file_1.py'
removed 'file_2.py'

# copy everything except .git from temp (checked out at 49a732c) into working directory
# (so working directory is identical to project at commit 49a732c)
me@laptop:~/Desktop/proj$ cp -nr ../temp/* ./

# make new commit identical to project state at 49a732c
me@laptop:~/Desktop/proj$ git add *
me@laptop:~/Desktop/proj$ git add -u
me@laptop:~/Desktop/proj$ git commit -m “Restore project to commit 49a732c.”
[master 2b6416c] Restore project to commit 49a732c.
 3 files changed, 18 deletions(-)

# remove temp
me@laptop:~/Desktop/proj$ rm -rf ../temp

# new commit 2b6416c is now identical to 49a732c

或者,如果分支是執行此操作的最佳方法,是否有一系列命令將始終有效並且不會產生任何合並沖突或告訴您使用git stash(假設當前工作目錄是干凈的)?

要創建新的提交,還原舊提交的內容,您可以:

  • 首先,標記您分支的當前HEAD(此處為master ):我們將需要移動該HEAD 而不修改master ,因此讓我們在master所在的位置創建一個名為“ tmp ”的新臨時分支。

     git checkout master git checkout -b tmp 

(是的,這與問題的“無分支”相反,但是您將很快刪除該tmp分支)

  • 然后,我們返回內容正確的舊提交。

     git reset --hard <old_commit> 

這會將索引(和工作樹)重置為正確的內容,但同時也會移動HEAD。 但是,這會移動tmp HEAD,而不是master HEAD。

  • tmp HEAD移回master所在的位置,但不修改索引或工作樹(這表示我們需要進行新的提交)

     git reset --soft master 
  • master / tmp HEAD頂部進行一次新提交,代表正確的內容(舊提交)。

     git commit -m "new commit, image of an old one" 
  • 最后,迫使master成為tmp所在的位置:稍后再進行一次新提交。

     git branch -M tmp master git checkout master git branch -d tmp 

現在,常規的git push就足夠了,任何協作者都可以像往常一樣簡單地進行拉動,並且仍然可以獲取舊的重置內容。

git push

在要返回某種狀態的情況下,請執行以下操作:

git reset --hard 49a732c

此步驟將您的master分支置於所需狀態。 如果要保存以前的分支狀態:

git checkout 48ah14s -b archive/my-unrecognized-experiments

重置后您仍然可以執行此操作,因為重置不會刪除提交。

PS分支是git必不可少的部分。 最好先講授分支,然后再講授您所想象的復雜(以git為單位)的事物。

編輯如果您希望您的master與遙控器保持一致:

git reset 49a732c # move HEAD back, all changes still in working tree
git commit -am "My unrecognized experiments" # save all changes as one commit
git reset --hard 48ah14s  # restore master HEAD
git revert <hash of my unrecognized experiments> # apply reverted changes to master

假設您從干凈的工作樹開始,則可以執行以下操作:

cd <root_directory_of_your_repo>
git checkout master
git checkout 49a732c -- .

當您指定一個文件(在這種情況下是. (倉庫的根目錄))作為git checkout的參數時,結帳不會切換分支(倉庫HEAD將保持不變)。 它只會更新索引,以使該文件與指定提交中的文件版本相匹配。 由於您已指定存儲庫的根目錄,因此索引中的所有文件都將更新以匹配指定的提交49a732c

暫無
暫無

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

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