繁体   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