【问题标题】:Git: How to move back and forth between commitsGit:如何在提交之间来回移动
【发布时间】:2011-01-08 10:31:21
【问题描述】:

我有一个关于 Git 的新手问题:

我需要在一个分支的历史中来回移动。 这意味着,我需要将所有文件恢复到它们在某个旧版本中所处的状态,然后我需要回到存储库中的最新状态。我不需要承诺。

使用 SVN,它会是

svn up -r800

获得修订版 800,并且

svn up

与存储库同步。

我知道我想要返回的提交的哈希值,所以我尝试了

git reset <hash>

这似乎让我到了那里。但后来我尝试了

git pull

但这抱怨冲突。

那么,浏览分支历史的正确方法是什么?

我正在考虑 SVN,所以不要犹豫地向我指出一些不错的教程。请注意,我已经检查了 http://git.or.cz/course/svn.htmlhttp://www.youtube.com/watch?v=8dhZ9BXQgc4

谢谢,昂德拉。

【问题讨论】:

  • 旁注:我已经习惯完全避免git pull。相反,我在 bash 中使用 git fetch --all 别名为 gu,并一直打开 gitk,查看所有分支 - 请参阅查看 -> 编辑 -> 选中所有 4 个复选框。然后我使用git resetgist stash + git co 移动,这取决于我的需要。

标签: git reset pull git-pull


【解决方案1】:

嗯,我以前也是 svn 用户,现在我的所有项目都使用 git。

在使用 git 时,应该从 svn 中使用的客户端-服务器架构转变思维方式。在 svn 中,每次更改都需要与服务器建立连接。使用 git,您的 repo 位于工作目录中。您不需要为每个 repo 操作建立连接。

仅使用 git pushgit pull 与 repo 同步。可以将其想象为使用 rsync 或任何备份解决方案,以使两个地方具有完全相同的内容。就像您连接外部备份硬盘,然后将其中的内容与您的主内容相同。这就是git pullgit push的用法。

如果您只想来回查看历史记录,请使用git checkout。使用 git history 查看修订 ID。如果您使用的是 Linux,请使用 gitk 查看修订树。在 Windows 中,tortoise git 可以使用修订图来显示它。

要返回最新版本,请使用git checkout master。在执行任何命令之前,请始终让自己执行git status。此命令将显示您需要了解的有关当前回购条件的任何信息,以及您需要执行哪些操作才能使其正确。在执行git pullgit push 之前,最好确保git status 结果包含文本working directory clean

如果您需要将文件恢复到以前的版本,您可以使用git merge 来完成。在对文件执行此操作之前,请先使用git diff 对其进行测试。例如:git diff rev1:rev2 filename。它将打印出两个修订版之间的任何差异。 rev1 中的更改将替换为 rev2 中的更改。所以要进行还原,rev2 将比 rev1 旧。 diff结果满意后,用git merge做,把diff换成merge,其他参数不变。

我希望这对你有帮助。主要的关键是看到你的工作目录是你的回购。了解这一点将帮助您充分利用 git。祝你好运。

【讨论】:

    【解决方案2】:

    试试git reflog,它列出了你为在提交之间切换所做的提交和签出,甚至是你在签出到上一个提交时丢失的提交。

    然后你可以尝试git checkout &lt;hash of a commit&gt; 切换到该提交。

    希望这会有所帮助!

    【讨论】:

      【解决方案3】:

      其他答案提供了丰富的信息,但我相信这最接近 OP 想要的:

      将这两个函数添加到您的 ~/.bashrc 中:

      # checkout prev (older) revision
      git_prev() {
          git checkout HEAD~
      }
      
      # checkout next (newer) commit
      git_next() {
          BRANCH=`git show-ref | grep $(git show-ref -s -- HEAD) | sed 's|.*/\(.*\)|\1|' | grep -v HEAD | sort | uniq`
          HASH=`git rev-parse $BRANCH`
          PREV=`git rev-list --topo-order HEAD..$HASH | tail -1`
          git checkout $PREV
      }
      

      用法:

      $ git_prev
      Previous HEAD position was 7042c8a... Commit message2
      HEAD is now at d753ecc... Commit message1
      
      $ git_next
      Previous HEAD position was d753ecc... Commit message1
      HEAD is now at 7042c8a... Commit message2
      

      注意:这些命令总是进入detached HEAD 状态。如果您从当前签出的分支中git_prev 然后git_next,您最终将返回最新版本,但您将处于分离的 HEAD 状态。做git checkout BRANCH_NAME 恢复正常。

      【讨论】:

      • 一旦你在做这样的事情,看看 git 别名可能是值得的。
      • 我喜欢这个答案,它工作了一分钟,但现在当我运行 git_next 时,我得到了这个usage: grep [-abcDEFGHhIiJLlmnOoqRSsUVvwxZ] [-A num] [-B num] [-C[num]] [-e pattern] [-f file] [--binary-files=value] [--color=when] [--context[=num]] [--directories=action] [--label] [--line-buffered] [--null] [pattern] [file ...]
      • 我遇到了与上面相同的问题,这似乎是因为git show-ref -s -- HEAD~ 没有返回任何内容。我很幸运将git_next 的第一行替换为BRANCH=git branch --contains HEAD | grep -v HEAD | sort | uniq
      【解决方案4】:

      要签出文件的不同版本,请使用

      git checkout rev -- filename
      

      其中 rev 可以是提交的 ID、分支的名称、标签的名称或相对版本。

      使用git loggitk 查看版本以查看您想要的文件版本。

      要使这个版本的文件永久化,你需要提交文件:git add filename; git commit filename

      我不建议 git pull 检查版本,因为它会合并 - 可能会修改您当前的状态。

      在这种情况下你不需要使用git reset,除非你git add一个你决定不提交的文件。

      【讨论】:

      • sweet jeebus 这样做时要小心。我的同事执行此命令来尝试从我的分支中进行更改,消除了我大约一周的工作,并通过这样做将其推送到存储库...
      • 只要您的同事没有执行 push -f,您始终可以恢复他的提交并恢复丢失的工作。如果你可以访问他推送的仓库,即使是强制推送也可以通过 git reflog 恢复。此外,如果您仍然有您的分支,它是可以恢复的。但是,是的,你必须小心。
      【解决方案5】:

      您可以使用git checkout 签出任何提交,然后将其与分支名称一起使用以返回到指定分支。

      git checkout 带有提交 ID 而不是分支名称会将您从任何命名分支移至所谓的分离头

      如果您使用git reset,那么它会将您的分支本身移回旧状态,从而孤立可能不是您想要的最近提交。

      【讨论】:

      • checkout 的真正作用是什么?它是否通过在当前状态和给定提交的状态之间反向应用提交的补丁来将文件更改为给定提交的状态?
      • 我找到了git resetgit reset origin。我不会做任何提交,所以我是否放弃最近的提交都没有关系,只要它很容易恢复(这意味着,通过单个命令)。
      • git checkout 不会使更改永久化。为此,请使用 git merge。查看我的答案。
      • checkout 将索引/缓存/暂存区域重置为给定提交指定的树,然后更新工作树以匹配缓存。它不需要重新应用任何补丁;它只是在给定的提交中使用树。 (如果您将分支名称传递给它,它还会进行错误检查并更新已签出的分支。)
      猜你喜欢
      • 2021-05-20
      • 2014-01-02
      • 1970-01-01
      • 2014-06-07
      • 2017-12-16
      • 2020-05-22
      • 2015-07-02
      • 2015-11-18
      • 1970-01-01
      相关资源
      最近更新 更多