git push
我们有一个远程 git repo,我们通常在我们的开发服务器上部署,然后git pull
在我们的实时服务器上部署以获取该 repo 的最新推送版本。
但是,如果我们已经提交并推送了一些修订(没有git pull
在实时服务器上),我们如何才能执行git pull
引用我们想要的旧提交的操作?
例如git pull -r 3ef0dedda699f56dc1062b5dcc2c59f7ad93ede4
答案1
一旦您提取了存储库,您就可以:
git checkout 3ef0d...
答案2
uploadpack.allowReachableSHA1InWant
自从Git 2.5.0可以在服务器上启用此配置变量,这里GitHub 功能请求和GitHub 提交启用此功能。
Bitbucket Server 从 5.5+ 版本开始启用它。
用法:
# Make remote with 4 commits, and local with just one.
mkdir server
cd server
git init
touch 1
git add 1
git commit -m 1
git clone ./ ../local
for i in {2..4}; do
touch "$i"
git add "$i"
git commit -m "$i"
done
# Before last commit.
SHA3="$(git log --format='%H' --skip=1 -n1)"
# Last commit.
SHA4="$(git log --format='%H' -n1)"
# Failing control without feature.
cd ../local
# Does not give an error, but does not fetch either.
git fetch origin "$SHA3"
# Error.
git checkout "$SHA3"
# Enable the feature.
cd ../server
git config uploadpack.allowReachableSHA1InWant true
# Now it works.
cd ../local
git fetch origin "$SHA3"
git checkout "$SHA3"
# Error.
git checkout "$SHA4"
答案3
如果实时服务器上的某个进程立即访问刚刚拉取的内容(即拉取后无法使用git checkout 3ef0d
),则应考虑标记要在生产中部署的版本,并在生产中专门签出该标记,以便拉取不会立即更改您的工作目录。否则,您可能会冒着有人在您拉取之前推送的风险。
答案4
请注意,
git pull git checkout my-old-commit
现在会让您处于 DETACHED HEAD 状态 - 实际上,您正在将此存储库中的未来提交发送到新的提交路径。对于部署存储库来说,这不是一个主要问题,因为唯一的提交应该是在被拉取之前已经正确提交的提交。
但是,有时检查提交标记(head、tags、remotes)是否与主存储库相同很有用。要在结帐后修复此问题:
git reset
- 重新连接 head
git fetch
- 同步远程标记 [这可能取决于 git 版本 - 诚然,我们的环境仍为 1.7... 因此可能不再需要 YMMV]