244

I cloned a remote git repository about a month ago. The remote repository has undergone many changes and has now become unstable. Now I need another copy of the repository, version identical to the one I cloned a month ago.

How do I do this?

2

9 Answers 9

282

You could "reset" your repository to any commit you want (e.g. 1 month ago).

Use git-reset for that:

git clone [remote_address_here] my_repo
cd my_repo
git reset --hard [ENTER HERE THE COMMIT HASH YOU WANT]
7
  • 34
    You didn't mention it, but this will only reset the master branch, which is checked out by default on a clone. If a branch other than master is your main development branch that must be checked out first before git reset Commented Aug 24, 2010 at 9:53
  • 19
    why would you not do a simple checkout of the wanted commit?
    – nemoo
    Commented May 23, 2013 at 10:44
  • 10
    Because you will be on the "detached HEAD" state after checkout to a particular commit. Commented May 23, 2013 at 16:06
  • 8
    @RuiCarneiro it would be better to use git checkout -b new_branch hash you create a new branch based on the hash without touching to any other branch. Moving the head of an existing branch could cause problems when its time to push something to a remote server. Commented Jan 23, 2017 at 18:57
  • 1
    @YuriGhensev If the commit was already pushed to a remote branch you can do git pull origin [branch] otherwise, afaik, its lost. Commented Sep 22, 2017 at 8:00
136

You Can use simply

git checkout  commithash

in this sequence

git clone `URLTORepository`
cd `into your cloned folder`
git checkout commithash

commit hash looks like this "45ef55ac20ce2389c9180658fdba35f4a663d204"

1
  • 16
    I like this answer the best. I think a git reset --hard should be avoided, in favour of a git checkout commit-hash. A git reset --hard removes part of the git history which sometimes isn't desirable. Commented Oct 25, 2016 at 6:16
40

Use git log to find the revision you want to rollback to, and take note of the commit hash. After that, you have 2 options:

  1. If you plan to commit anything after that revision, I recommend you to checkout to a new branch: git checkout -b <new_branch_name> <hash>

  2. If you don't plan to commit anything after that revision, you can simply checkout without a branch: git checkout <hash> - NOTE: This will put your repository in a 'detached HEAD' state, which means its currently not attached to any branch - then you'll have some extra work to merge new commits to an actual branch.

Example:

$ git log
commit 89915b4cc0810a9c9e67b3706a2850c58120cf75
Author: Jardel Weyrich <suppressed>
Date:   Wed Aug 18 20:15:01 2010 -0300

    Added a custom extension.

commit 4553c1466c437bdd0b4e7bb35ed238cb5b39d7e7
Author: Jardel Weyrich <suppressed>
Date:   Wed Aug 18 20:13:48 2010 -0300

    Missing constness.

$ git checkout 4553c1466c437bdd0b4e7bb35ed238cb5b39d7e7
Note: moving to '4553c1466c437bdd0b4e7bb35ed238cb5b39d7e7'
which isn't a local branch
If you want to create a new branch from this checkout, you may do so
(now or later) by using -b with the checkout command again. Example:
  git checkout -b <new_branch_name>
HEAD is now at 4553c14... Missing constness.

That way you don't lose any informations, thus you can move to a newer revision when it becomes stable.

4
  • 2
    But also nothe that you are on a detached head, which is OK for read only operations. But when you intend to make changes starting at this revision, you need to create a new branch. See sitaramc.github.com/concepts/detached-head.html for more informations.
    – Rudi
    Commented Aug 24, 2010 at 13:23
  • @Rudi: Thank you. It was just an example to show the usage. Updated to mention it.
    – jweyrich
    Commented Aug 24, 2010 at 14:03
  • To get back to "working status" you can just git checkout develop where develop is the name of your branch. Commented Mar 18, 2014 at 10:37
  • 1
    @SteveTauber well, supposing you have a different branch that is working, changing to that branch is enough indeed.
    – jweyrich
    Commented Mar 18, 2014 at 10:55
37

If that version you need to obtain is either a branch or a tag then:

git clone -b branch_or_tag_name repo_address_or_path
0
5

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"
2

Unlike centralized version control systems, Git clones the entire repository, so you don't only get the current remote files, but the whole history. You local repository will include all this.

There might have been tags to mark a particular version at the time. If not, you can create them yourself locally. A good way to do this is to use git log or perhaps more visually with tools like gitk (perhaps gitk --all to see all the branches and tags). If you can spot the commits hashes that were used at the time, you can tag them using git tag <hash> and then check those out in new working copies (for example git checkout -b new_branch_name tag_name or directly with the hash instead of the tag name).

2

You can solve it like this:

git reset --hard sha

where sha e.g.: 85a108ec5d8443626c690a84bc7901195d19c446

You can get the desired sha with the command:

git log
0

The source tree you are requiring is still available within the git repository, however, you will need the SHA1 of the commit that you are interested in. I would assume that you can get the SHA1 from the current clone you have?

If you can get that SHA1, the you can create a branch / reset there to have the identical repository.

Commands as per Rui's answer

0

Probably git reset solves your problem.

git reset --hard -#commit hash-

Not the answer you're looking for? Browse other questions tagged or ask your own question.