如何强制Git在每次Pull时覆盖所有内容?

233

我有一个中央裸仓库,有三个开发者仓库正常地从它拉取和推送。

我还有两个其他的仓库从中央裸仓库中拉取:一个是实时服务器,另一个是测试/预发布服务器 -- 每个都从自己的分支拉取。

情景是这样的:我在中央仓库上有一个post-update hook脚本,自动访问测试和实时仓库,并在每个仓库上运行拉取命令。这将更新所有依赖于新提交的分支的测试和实时服务器。这一切工作得很好。

问题是:在紧急情况下,可能会直接在服务器上更新文件(通过ftp或其他方式),然后中央 post-update 脚本将失败,因为会发生合并/覆盖冲突。无法避免这种情况,它是不可避免的。

我希望发生的情况是这样的:我希望从实时和测试站点拉取时始终进行覆盖/合并。始终如此。这些仓库只拉取,因为它们不用于开发。

在我的所有研究中,我找不到一个好的解决方案,可以使拉取始终 强制覆盖本地文件。这是否可能?如果是这样,它将成为一个很好的开发场景。


1
虽然我已经投票支持下面的“重置为刚刚获取的内容”答案,但我认为解决你真正问题的方法是不要进行带外更改。无论多么紧急,修改都应该始终通过版本控制进行。除操作员外,没有人应该直接访问运行站点(例如,不是开发人员)。始终使用版本控制意味着您有记录更改时间和更改者以及更好的工具来处理它们。为什么要为了没有实际好处而破坏它呢? - Phil Miller
1
@Novelocrat,我明白你的意思。不幸的是,有许多情况下,有人可以直接上传文件到服务器。在这种情况下,我需要运行一些命令来重新同步存储库。以前,我们使用FTP脚本将文件从存储库移动到服务器。上述提议的方法将简单地消除FTP步骤,这在过去非常有效。 - bmilesp
3
因此,不要让人们直接访问服务器。锁定FTP和SSH访问,或告诉他们如果进行不可解释的更改将被解雇。让这种做法继续下去只会在长期内伤害你和你的团队。 - Phil Miller
7个回答

578

实际上,这样做的理想方式是根本不使用pull,而是使用fetchreset

git fetch origin master
git reset --hard FETCH_HEAD
git clean -df

(将 master 更改为您想要跟随的任何分支。)

pull 的设计是围绕合并更改的方式,而 reset 的设计则是简单地使您的本地副本与特定提交匹配。

根据您系统的需求,您可能需要考虑稍微不同的选项来使用 clean


3
reset --hard 是一个命令,用于强制将工作目录(和当前分支)的状态重置为与特定提交相匹配的状态。 - Amber
27
FETCH_HEAD是由fetch自动创建的引用,表示已获取的引用。它不会被合并,每次执行Fetch操作时都会直接覆盖。clean是一个命令,用于删除git未跟踪的文件,-df标志表示同时删除目录(-d)并实际执行删除操作(-f)。 - Amber
5
为什么没有一个关键词来表达这个意思?我需要这个比“pull”更频繁。 - Wolfgang Fahl
20
在使用 git clean -df 前,您可能想要使用 git clean -dn,这样您就可以看到将被删除的文件/文件夹。如果您有备份,才能撤销 git clean -df 的操作。请注意,不要改变原文意思,尽量使译文通俗易懂。 - Ibrahim Lawal
3
@NickMiddleweek 我曾经担心 git clean -df 也会删除被 Git 忽略的文件,但事实证明它不会。git clean --help 中写道:“通常只会删除 Git 不知道的文件,但如果指定了 -x 选项,则也会删除被忽略的文件。例如,这可以用于删除所有构建产品。” - nickang
显示剩余5条评论

23

12

要从源头拉取一个分支的副本并强制覆盖本地文件,请使用以下命令:

结果为:

要从源头拉取一个分支的副本并强制覆盖本地文件,请使用以下命令:

git reset --hard origin/current_branch

所有当前的工作都将丢失,然后它将与原始分支相同。


12
git reset --hard HEAD
git fetch --all
git reset --hard origin/your_branch

7

我不确定要如何用一个命令来完成,但你可以尝试以下方式:

git reset --hard
git pull

甚至更多
git stash
git pull

1
运行以下命令:git reset --hard && git pull。或者,但不是更好的选择,git reset --hard; git pull。使用 && 只有在第一个命令成功执行后才会运行第二个命令。; 无论第一个命令的退出代码如何都会运行第二个命令。 - mazunki

2
如果您自上次拉取/克隆以来还没有提交本地更改,则可以使用以下命令:

git stash

git checkout *
git pull

checkout会清除您与上次本地提交的本地更改,而pull将把它与远程存储库同步。


2
您可以更改钩子来清除所有内容。
# Danger! Wipes local data!

# Remove all local changes to tracked files
git reset --hard HEAD

# Remove all untracked files and directories
git clean -dfx

git pull ...

2
x是做什么的?请解释一下开关。 - Stephan Kristyn
2
x 应该会删除所有未跟踪的文件,我想。很难在 manpage 的术语中理解,这就是为什么我们有 SO 的原因。 - JosephK
2
@JosephK:那是不正确的。git clean 的基本目的已经是“从工作树中删除未跟踪的文件”(页面顶部)。通常,这不包括被忽略的文件,但 -x 告诉 git clean 也包括被忽略的文件(除非这些文件被 -e 选项忽略)。 - Dietrich Epp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接