【问题标题】:Git command to checkout any branch and overwrite local changesGit 命令签出任何分支并覆盖本地更改
【发布时间】:2013-08-31 11:29:22
【问题描述】:

是否有一个 Git 命令(或一小段命令)可以安全可靠地执行以下操作?

  • 摆脱任何本地更改。
  • 如有必要,从原点获取给定分支
  • 签出给定的分支?

目前我被困在:

git fetch -p
git stash
git stash drop
git checkout $branch
git pull

但这让我很困扰,因为我被要求输入密码两次(fetchpull)。 一般来说,只要密码只需要一次,我就会对任何解决方案感到满意。

几点说明:

  • 它是应用程序自制部署脚本的一部分(代码托管在 GitHub 上)。
  • 分支是否已从源获取应该没有区别(即,新分支的首次部署理想情况下不需要任何额外步骤)。
  • 该脚本位于可供多人访问的远程计算机上,因此不会存储任何凭据,并且必须输入用户/密码(但如果可能,只需输入一次)。
  • 我不关心任何本地更改;我总是想要给定分支的原始副本(部署脚本的另一部分会产生本地更改)。
  • 我无法每次都克隆或导出新的存储库;太费时间了。

【问题讨论】:

  • 1. git reset --hard 2. git checkout $branch 3. git pull origin $branch
  • 仅供参考,如果您使用 ssh 密钥,您将永远不会被提示输入密码。
  • @Slam 如果您使用的是 GitLab,则不会。

标签: git deployment git-checkout


【解决方案1】:

您可以遵循类似于 "How do I force “git pull” to overwrite local files?" 的解决方案:

git fetch --all
git reset --hard origin/abranch
git checkout abranch 

这将只涉及一次提取。

对于 Git 2.23+,git checkout 在此处替换为 git switch (presented here)(仍处于试验阶段)。

git switch -f $branch

(与-f being an alias for --discard-changes,如Jananswer 中所述)

即使索引或工作树与 HEAD 不同,也要继续。
恢复索引和工作树以匹配切换目标。


如果您想要切换分支,而只是恢复另一个分支的文件夹,那么git restore是另一个命令它取代了旧的过时和令人困惑的git checkout
我提交了git restore here

git restore --source=anotherBranch --staged] [--worktree -- aFolder
# or, shorter:
git restore -s anotherBranch -SW -- aFolder

【讨论】:

  • 我正在使用这个方案,但是我在最后添加了额外的git checkout $branch,因为否则git返回的当前分支信息是错误的。
  • @VonC,谢谢。这确实已经用分支覆盖了 master。
  • @tuxErrante 那么你不想切换分支吗?在这种情况下,git restore 适合您。没有人应该在 2021 年使用 git checkout。它是旧的、过时的和令人困惑的。 git restore -s experiment -SW -- aFolder:这将从分支 experiment 恢复 aFolder 内容,包括工作树 (W) 和索引 (S)。
  • @tuxErrante 我已经编辑了答案以使区分(切换分支和恢复内容之间)更清晰。
  • @MikeSchinkel 这似乎是一个错字。我已编辑答案以使用与获取的分支相同的名称。
【解决方案2】:

几点:

  • 我相信git stash + git stash drop 可以替换为git reset --hard
  • ...或者,更短,将-f 添加到checkout 命令:

    git checkout -f -b $branch
    

    这将丢弃任何本地更改,就像在结帐之前使用了git reset --hard

至于主要问题: 而不是最后一步,您可以将适当的分支从远程合并到本地分支:git merge $branch origin/$branch,我相信它不会命中远程。如果是这种情况,它就不需要凭证,从而解决您最关心的问题。

【讨论】:

  • -b 可能需要大写。 git checkout -f -B $branch 如果本地分支已经存在,则重置它。
  • 只是git checkout -B $existing_branch_name 为我工作,而git checkout -f -b $existing_branch_name 没有——就像@xer0x 所说,我认为答案不正确,因为大写-B 是必需的?
【解决方案3】:

git resetgit clean 在某些情况下可能会过大(并且会浪费大量时间)。

如果您只是收到“以下未跟踪文件将被覆盖...”之类的消息,并且您希望远程/源/上游覆盖那些冲突的未跟踪文件,那么git checkout -f <branch> 是最佳选择。

如果您像我一样,您的另一个选择是清理并执行--hard reset,然后重新编译您的项目。

【讨论】:

    【解决方案4】:

    新的git-switch command(从 GIT 2.23 开始)还有一个标志 --discard-changes,应该可以帮助你。之后可能需要git pull

    警告:它仍被认为是实验性的。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-24
    • 2012-12-20
    • 2018-11-04
    • 2016-12-11
    • 2017-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多