有没有一种简单的方法可以使用 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
Run Code Online (Sandbox Code Playgroud)
或者,如果分支是执行此操作的最佳方法,是否有一系列命令始终有效并且不会产生任何合并冲突或告诉您使用 git stash(假设当前工作目录是干净的)?
Von*_*onC 10
要创建新提交,恢复旧提交的内容,您可以:
首先,标记分支的当前 HEAD(假设master在这里):我们需要移动该 HEAD而不修改master,因此让我们创建一个名为“ tmp”的新临时分支where masteris。
git checkout master
git checkout -b tmp
Run Code Online (Sandbox Code Playgroud)(是的,这与问题的“无分支”相反,但您很快就会删除该 tmp 分支)
然后我们回到具有正确内容的旧提交。
git reset --hard <old_commit>
Run Code Online (Sandbox Code Playgroud)这会将索引(和工作树)重置为正确的内容,但这也会移动 HEAD。但是,这会移动tmpHEAD,而不是masterHEAD。
将tmpHEAD移回where masteris,但不修改索引或工作树(它们代表我们新提交所需的内容)
git reset --soft master
Run Code Online (Sandbox Code Playgroud)在master/ tmpHEAD之上进行一个新的提交,它代表正确的内容(旧的提交)。
git commit -m "new commit, image of an old one"
Run Code Online (Sandbox Code Playgroud)最后,强制master到哪里tmp是:稍后进行一次新的提交。
git branch -M tmp master
git checkout master
git branch -d tmp
Run Code Online (Sandbox Code Playgroud)现在一个普通的git push就足够了,任何合作者都可以像往常一样简单地拉动,仍然可以获得旧的重置内容。
git push
Run Code Online (Sandbox Code Playgroud)
假设您从一个干净的工作树开始,您可以这样做:
cd <root_directory_of_your_repo>
git checkout master
git checkout 49a732c -- .
Run Code Online (Sandbox Code Playgroud)
当您指定一个文件(在本例中.为(存储库的根目录))作为 的参数时git checkout,签出将不会切换分支(存储库HEAD将保持不变)。它只会更新索引以使该文件与指定提交中的该文件的版本匹配。由于您指定了存储库的根目录,索引中的所有文件都将更新以匹配指定的提交49a732c
| 归档时间: |
|
| 查看次数: |
2631 次 |
| 最近记录: |