将分支指针移动到不同的提交而不签出

Mot*_*Mot 704 git git-branch

要移动已签出分支的分支指针,可以使用该git reset --hard命令.但是如何移动未检出分支的分支指针指向不同的提交(保留所有其他东西,如跟踪的远程分支)?

Chr*_*sen 902

git branch -f <branch-name> <new-tip-commit>
Run Code Online (Sandbox Code Playgroud)

  • 或者对于任意引用,`git update-ref -m"reset:将<branch>重置为<new commit>"<branch> <commit>`.(如果你愿意的话,你可以选择关于reflog消息的尼特 - 我相信`branch -f`一个与`reset --hard`一个不同,这不是它们中的任何一个.) (23认同)
  • 如果你想要移动的分支是你当前的分支(`HEAD`指向它),这将不起作用. (20认同)
  • 这是一个更好的答案,因为它处理99%的情况并且实际上符合文档.`git help branch`表示"-f, - force重置<branchname>到<startpoint>如果<branchname>已经存在.没有-f git branch拒绝更改现有分支." (15认同)
  • 我正在做`git branch -f master <hash>`它告诉我'致命:不能强制更新当前分支.嗯我现在必须做什么,在允许我使用它之前检查一些其他随机分支命令? (12认同)
  • @ pelle-ten-cate但你不能接受他们! (5认同)
  • Jefromi,请写一个单独的答案,以便获得投票.:) (4认同)
  • @Qwertie:您可以使用`git reset --soft <hash>`来改变HEAD(即当前分支;假设HEAD未分离). (2认同)
  • 什么是“新提示提交”? (2认同)
  • 这似乎有副作用。如果您的“new-tip-commit”是远程分支,它也会被设置为“branch-name”的上游。有没有解决的办法? (2认同)

Ada*_*m A 532

注意如果您只是想将分支移动到另一个提交,最简单的方法是

git branch -f branch-name new-tip-commit

详见Chris Johnsen的回答.

你可以为任意引用做到这一点.这是如何移动分支指针:

git update-ref -m "reset: Reset <branch> to <new commit>" refs/heads/<branch> <commit>
Run Code Online (Sandbox Code Playgroud)

一般形式:

git update-ref -m "reset: Reset <branch> to <new commit>" <ref> <commit>
Run Code Online (Sandbox Code Playgroud)

如果你愿意的话,你可以选择关于reflog消息的尼特 - 我相信它与那个branch -f不同reset --hard,而且这不是它们中的任何一个.

  • 消息在哪里有用?它存放在哪里以及以后如何阅读? (35认同)
  • 如果像我一样,你不小心使用<branch>而不是refs/heads/<branch>,你最终会在.git目录下的.git/<branch>中找到一个新文件,你会得到像当你尝试使用它时,"refname'master'是不明确的".您可以从.git目录中删除该文件以进行修复. (34认同)
  • 它没有被解释为满足为什么这比`git branch -f`更好.具体而言,这种方法似乎是:(A)难以使用(B)更难记住,(C)更危险 (25认同)
  • "究竟是什么意思是任意引用" - 分支并不是唯一一种指向提交的引用.有标签,你也可以自己创建任意refs/whatevs/myref样式参考,既不是分支也不是标签.我相信这也解答了Steven Lu关于这可能"更好"的问题.我同意分支-f是最简单的,如果你正在与分支机构合作. (9认同)
  • 看到已经有6个月了,Jefromi没有将他/她的评论转变为答案,我将其作为社区维基进行,以便获得曝光.直到我做了一个分支-f,我个人才看到它! (3认同)
  • *注意:*这不适用于裸存储库.在裸存储库中,您必须使用'git branch -f master <commit>'来更新分支(请参阅下面的答案). (3认同)
  • 究竟是什么意思"任意引用"?如果我没有弄错的话,克里斯约翰森在下面的答案将从任意提交中分支出来. (2认同)

Ami*_*tin 131

您还可以传递git reset --hard提交引用.

例如:

git checkout branch-name
git reset --hard new-tip-commit
Run Code Online (Sandbox Code Playgroud)

我发现我半经常做这样的事情:

假设这段历史

$ git log --decorate --oneline --graph
* 3daed46 (HEAD, master) New thing I shouldn't have committed to master
* a0d9687 This is the commit that I actually want to be master

# Backup my latest commit to a wip branch
$ git branch wip_doing_stuff

# Ditch that commit on this branch
$ git reset --hard HEAD^

# Now my changes are in a new branch
$ git log --decorate --oneline --graph
* 3daed46 (wip_doing_stuff) New thing I shouldn't have committed to master
* a0d9687 (HEAD, master) This is the commit that I actually want to be master
Run Code Online (Sandbox Code Playgroud)

  • 您是否注意到您的"答案"没有添加任何不属于问题的部分? - OP说:如果检查出来......你可以使用`git reset --hard ...`这里不需要重复!:-( (13认同)
  • 如果您的工作树干净,这很好.如果您有许多阶段性或非阶段性更改,那么最好像上面讨论的那样执行`git update-ref`. (11认同)
  • @WilsonF,也许你在这里找到这个很好,但它根本没有回答这个问题.也许这是其他问题的答案,但这里是_wrong_. (7认同)
  • @Robert:我不同意.问题并没有说_how_使用它,这样做.很高兴不去寻找那种方式. (6认同)
  • 我认为这可能应该是对问题的评论,而不是答案。(或者也许它正在回答问题的早期版本?) (4认同)

Mat*_*ipe 42

只是为了丰富讨论,如果你想将myBranch分支移动到你当前的提交,只需省略第二个参数-f

例:

git branch -f myBranch


当我rebase处于独立HEAD状态时,我通常会这样做:)


alo*_*ono 23

Git 2.23.0 引入了git-switch也可用于执行此操作的命令。

git switch -C <branch-name> [<start-point>]
Run Code Online (Sandbox Code Playgroud)

(大写C)选项-C表示如果<branch-name>已经存在,则将其重置为<start-point>

使用-c(小写 C),它将尝试创建一个新分支,但如果分支已经存在,则会失败。

<start-point>可以是哈希、标签或其他分支名称。


小智 14

如果要将未签出的分支移动到另一个提交,最简单的方法是使用 -f 选项运行 gitbranch 命令,该选项确定分支 HEAD 应指向的位置:

git branch -f <branch-name> (<sha1-commit-hash> or <branch-name>)
Run Code Online (Sandbox Code Playgroud)

例如,如果您希望本地开发分支跟踪远程(原始)开发分支:

git branch -f develop origin/develop
Run Code Online (Sandbox Code Playgroud)

请小心,因为如果您尝试移动的分支是您当前的分支,则此操作将不起作用。要移动分支指针,请运行以下命令:

git update-ref -m "reset: Reset <branch-name> to <sha1-commit-hash>" \
  refs/heads/<branch-name> <sha1-commit-hash>`
Run Code Online (Sandbox Code Playgroud)

git update-ref 命令安全地更新存储在 ref 中的对象名称。

希望我的回答对你有帮助。信息来源是这个片段


Pet*_*des 13

gitk --all:

  • 右键单击您想要的提交
  • - > 创建新分支
  • 输入现有分支的名称
  • 确认更换该名称的旧分支的对话框上按回车键.

请注意,重新创建而不是修改现有分支将丢失跟踪分支信息.(对于简单的用例而言,这通常不是问题,因为只有一个远程和你的本地分支与远程中相应的分支具有相同的名称.请参阅注释以获取更多详细信息,感谢@mbdevpl指出这一缺点.)

如果gitk有一个功能,对话框有3个选项,那将会很酷:覆盖,修改现有或取消.


即使你通常是像我一样的命令行瘾君子,git gui并且gitk它们设计得非常适合他们允许的git用法子集.我强烈建议将它们用于他们擅长的东西(即选择性地在git gui中进入/退出索引,并且还提交.(ctrl-s添加一个签名:line,ctrl-enter to commit .)

gitk 非常适合跟踪一些分支,同时将您的更改整理成一个很好的补丁系列以提交上游,或者您需要跟踪多个分支中间的内容.

我甚至没有打开图形文件浏览器,但我喜欢gitk/git gui.


Adr*_*ian 8

老实说,我很惊讶没有人想到这个git push命令:

git push -f . <destination>:<branch>
Run Code Online (Sandbox Code Playgroud)

点 ( . ) 指的是本地存储库,您可能需要 -f 选项,因为目标可能“在其远程副本之后”

尽管此命令用于将更改保存在服务器中,但结果与将远程分支 ( <branch>)移动到与本地分支 ( <destination>)相同的提交完全相同

  • 您也可以在不使用“-f”的情况下执行此操作,以避免破坏任何本地内容;例如,“git fetch origin &amp;&amp; git push”。origin/develop:develop` 是 `git checkoutdevelopment &amp;&amp; git pull --ff-only` 的无需签出的快速失败版本 (2认同)

ax.*_*ax. 7

建议的解决方法git branch -f branch-pointer-to-move new-pointerTortoiseGit:

  • "Git Show日志"
  • 检查"所有分支"
  • 在你希望分支指针移动到(新指针)的行上:
    • 右键单击"在此版本中创建分支"
    • 在"Branch"旁边,输入要移动的分支的名称(branch-pointer-to-move)
    • 在"Base On"下,检查新指针是否正确
    • 检查"强制"

在此输入图像描述

在此输入图像描述


Gui*_*rez 5

打开文件.git/refs/heads/<your_branch_name>,并将存储在其中的哈希值更改为您想要将分支头移动到的位置。只需使用任何文本编辑器编辑并保存文件即可。只需确保要修改的分支不是当前活动的分支即可。

免责声明:可能不是一个可取的方法,但可以完成工作。

  • 不确定这是混乱还是邪恶的做法。 (4认同)
  • @KeithRussell,@G 简直太混乱了,除非你搞乱了公共仓库!:-) 从某种意义上说,这是一种受支持的方法,因为 git 文档非常详细地描述了其内部工作原理。能够了解哪些文件是如何更新的,例如“git commit”,是使用 git 而不是 Mercurial 的最令人信服的原因。 (3认同)