Git:如何用上一个提交替换当前的工作目录,而不进行分支或git revert?

时间:2018-08-13 03:54:07

标签: git

使用git有简单的方法吗?

commit copy paste diagram

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

我不想使用分支,因为我正在向从未使用过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(假设当前工作目录是干净的)? / p>

3 个答案:

答案 0 :(得分:2)

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

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

    git checkout master
    git checkout -b tmp
    

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

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

    git reset --hard <old_commit>
    

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

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

    git reset --soft master
    
  • master / tmp HEAD的顶部进行新提交,该提交代表正确的内容(旧提交)。

    git commit -m "new commit, image of an old one"
    
  • 最后,强制mastertmp所在的位置:稍后再提交一次。

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

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

git push

答案 1 :(得分:0)

在要返回某种状态的情况下,请执行以下操作:

08-13 12:16:36.306 20983-20983 E/JL: [ main: (WeexPageFragment.java:59) loadWeex ] - renderhttp://172.16.43.62:8080/dist/hello.js 08-13 12:16:36.306 20983-20983 D/WXSDKInstance: Start render page: 08-13 12:16:36.308 20983-21003 D/weex: createInstance >>>> instanceId:1, options:{}, data: callJS >>>> instanceId:1function:createInstance 08-13 12:16:36.342 20983-21003 D/jsLog: [JS Framework] COMPATIBILITY WARNING: Weex DSL 1.0 (.we) framework is no longer supported! It will be removed in the next version of WeexSDK, your page would be crash if you still using the ".we" framework. Please upgrade it to Vue.js or Rax.__ERROR 08-13 12:16:36.360 20983-21003 E/jsengine: ReportException : Exception: SyntaxError: Unexpected token '}'. Cannot parse statement. at (global function):8 Function@[native code] Function@[native code] (weex framework):1:148499 ei@(weex framework):1:148517 createInstance@(weex framework):1:151735 (weex framework):1:255299 08-13 12:16:36.360 20983-21003 E/weex: reportJSException >>>> instanceId:1, exception function:createInstance, exception:Exception: SyntaxError: Unexpected token '}'. Cannot parse statement. at (global function):8 Function@[native code] Function@[native code] (weex framework):1:148499 ei@(weex framework):1:148517 createInstance@(weex framework):1:151735 (weex framework):1:255299

此步骤将您的git reset --hard 49a732c分支置于所需状态。如果要保存以前的分支状态:

master

重置后您仍然可以执行此操作,因为重置不会删除提交。

PS分支是git必不可少的部分。最好先讲授分支,然后再讲授您所想象的复杂(以git为单位)的事情。

编辑 如果您希望git checkout 48ah14s -b archive/my-unrecognized-experiments与遥控器保持一致:

master

答案 2 :(得分:0)

假设您从干净的工作树开始,您可以这样做:

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

当您指定文件(在这种情况下为.(仓库的根目录))作为git checkout的参数时,结帐将不会切换分支(仓库HEAD将保持不变)。它只会更新索引,以使该文件与指定提交中的文件版本相匹配。由于您已指定存储库的根目录,因此索引中的所有文件都将更新以匹配指定的提交49a732c