Git:如何用上一个提交而不是分支或git revert替换当前的工作目录? [英] Git: How do you replace your current working directory with a previous commit without branching or git revert?

查看:160
本文介绍了Git:如何用上一个提交而不是分支或git revert替换当前的工作目录?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有使用git进行跟踪的简单方法?

Is there an easy way to the following with git?

基本上,我想在提交历史记录的顶部创建一个新提交,该操作等同于历史记录中的先前提交(例如,将项目还原到以前的状态).

Basically I want to create a new commit at the top of my commit history that is equivalent to a previous commit from my history (e.g. to restore a project to a previous state).

我不想使用分支,因为我正在向从未使用过git的人讲授此内容,并且我希望保持事物尽可能线性". (我的大多数听众只需要备份内容,查看项目历史记录,并在必要时将项目还原到以前的状态,但没有别的选择.)

I don’t want to use branches because I’m teaching this to people who have never used git before, and I want to keep things as "linear" as possible. (Most of my audience just needs to back stuff up, review project history, and restore a project to a previous state if necessary, but nothing else remotely fancy.)

我不想使用git revert --no-commit 49a732c..HEAD,因为如果49a732c之后确实存在合并,这会给出一条错误消息(我承认我的听众不太可能这样做,但是有时它会通过疯狂尝试来发生使错误消息消失).

I don’t want to use git revert --no-commit 49a732c..HEAD because this gives an error message if there does happen to be a merge after 49a732c (which I admit is unlikely in my audience, but it does sometimes happen through frantic attempts to make error messages go away).

我也不想删除/重写历史记录.

I also don’t want to delete/rewrite history.

从本质上讲,有没有更简单的方法可以做到这一点?

Essentially, is there a simpler way to do this?

# 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(假设当前工作目录是干净的)? /p>

Alternatively, if branching is the best way to do this, is there a sequence of commands that will always work and won't yield any merge conflicts or tell you to use git stash (assuming current working directory is clean)?

推荐答案

要创建新的提交,还原旧提交的内容,您可以:

To create a new commit, restoring the content of an old commit, you can:

  • 首先,标记分支的当前HEAD(在这里假设master):我们将需要移动该HEAD ,而无需修改master,所以我们创建一个新的临时分支称为"tmp",其中master所在.

  • First, mark the current HEAD of your branch (assuming master here): we will need to move that HEAD without modifying master, so let's create a new temporary branch called 'tmp' where master is.

git checkout master
git checkout -b tmp

(是的,这与问题的无分支"相反,但是您将很快删除该tmp分支)

(yes, that is against the "without branching" of the question, but you will delete that tmp branch soon)

  • 然后,我们返回内容正确的旧提交.

  • Then we go back to an older commit with the right content.

git reset --hard <old_commit>

这会将索引(和工作树)重置为正确的内容,但同时还会移动HEAD.但是,这将移动tmp HEAD,而不移动master HEAD.

That resets the index (and working tree) to the right content, but that also moves HEAD. However, that moves tmp HEAD, not master HEAD.

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

  • move back tmp HEAD to where master is, but without modifying the index or the working tree (which are representing what we need for a new commit)

git reset --soft master

  • master/tmp HEAD的顶部进行一次新提交,该提交代表正确的内容(旧提交).

  • make a new commit, on top of master/tmp HEAD, which represents the right content (the old commit).

    git commit -m "new commit, image of an old one"
    

  • 最后,强制mastertmp所在的位置:稍后再提交一次.

  • Finally, force master to be where tmp is: one new commit later.

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

  • 现在普通的git push就足够了,任何协作者都可以像往常一样简单地拉动,并且仍然可以获取旧的重置内容.

    Now a regular git push is enough, any collaborator can simply pull as usual, and still get the old reset content.

    git push
    

    这篇关于Git:如何用上一个提交而不是分支或git revert替换当前的工作目录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆