66

We have a remote git repo that we normally deploy from using git push on our dev server then git pull on on our live servers to get the latest pushed version of the repo.

But if we have committed and pushed a few revisions (without a git pull on the live servers) how can we do a git pull that is referring to the older commit that we want?

i.e. something like git pull -r 3ef0dedda699f56dc1062b5dcc2c59f7ad93ede4

4 Answers 4

78

Once you've pulled the repository you should be able to go:

git checkout 3ef0d...
2
  • 1
    Nice, this worked perfectly. Also noticed that if I want to get back in sync for future pulls I need to specify the remote server when doing the next pull (i.e. git pull server:repo vs the regular git pull)
    – dlrust
    Feb 26, 2010 at 19:01
  • 4
    Maybe OP asked the wrong question, but for me it's the correct question and this is no answer. There is a specific commit on the server that is missing locally. The commit isn't part of a branch nor of a tag and it isn't trasnfered with a pull/fetch. How to fetch a specific commit?
    – BlackEye
    Apr 30, 2019 at 9:40
13

uploadpack.allowReachableSHA1InWant

Since Git 2.5.0 this configuration variable can be enabled on the server, here the GitHub feature request and the GitHub commit enabling this feature.

Bitbucket Server enabled it since version 5.5+.

Usage:

# 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"
1
  • There's also allowAnySHA1InWant now, however these are security features, make sure you understand the implications.
    – MarcH
    Dec 10, 2019 at 18:51
2

If some process on your live server immediately accesses the just-pulled content (i.e. you cannot work with git checkout 3ef0d after pull), you should consider tagging the version you want to deploy in production and specifically checkout that tag on production, so that pulling does not immediately change your working directory. Otherwise you'd risk somebody pushing just prior to your pull.

1

Note that a git pull git checkout my-old-commit now leaves you in a DETACHED HEAD state - effectively you're sending future commits in this repository down a new commit path. For a deployment repo this is not a major issue, since the only commits should be ones already committed correctly before being pulled.

However, its sometimes useful to check that the commit markers (head,tags,remotes) look identical to the master repo. To fix this following your checkout: git reset - reattaches the head git fetch - syncs the markers for remotes [this may be git version dependent - admittedly our environment is still on 1.7... so might no longer be required YMMV]

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .