How can I clone git repository with specific revision, something like I usually do in Mercurial:
hg clone -r 3 /path/to/repository
How can I clone git repository with specific revision, something like I usually do in Mercurial:
hg clone -r 3 /path/to/repository
To clone only one single specific commit on a particular branch or tag use:
git clone --depth=1 --branch NAME https://github.com/your/repo.git
Unfortunately, NAME can only be branch name or tag name (not commit SHA).
Omit the --depth flag to download the whole history and then checkout that branch or tag:
git clone --branch NAME https://github.com/your/repo.git
This works with recent version of git (I did it with version 2.18.0).
Just to sum things up (git v. 1.7.2.1):
git clone where you want the repo (gets everything to date — I know, not what is wanted, we're getting there) git checkout <sha1 rev> of the rev you wantgit reset --hardgit checkout -b masterNo need to download the whole history, and no need to call git init:
git clone --depth=1 URL
git fetch --depth=1 origin SHA1
git checkout SHA1
git branch -D @{-1} # if you want to tidy up the fetched branch
This has the disadvantage, to CB Baileys answer, that you will still download 1 unnecessary revision. But it's technically a git clone (which the OP wants), and it does not force you to download the whole history of some branch.
# clone special tag/branch without history
git clone --branch=<tag/branch> --depth=1 <repository>
# clone special revision with minimal histories
git clone --branch <branch> <repository> --shallow-since=yyyy-MM-ddTHH:mm:ss # get the commit time
cd <dir>
git reset --hard <revision>
you can't get a revision without histories if not set uploadpack.allowReachableSHA1InWant=true on server side, while you can create a tag for it and clone the special tag instead.
I was able to accomplish this using the git clone --config option, which I learned from this answer: https://stackoverflow.com/a/43759576/1330650
My scenario involves a sparse checkout in an Azure DevOps pipeline, where I need to clone a repo using a commit hash, not a branch name. The clone command doesn't accept a commit hash as a parameter. The workaround is to set a configuration variable (-c) containing a refspec, because that refspec can use a commit hash instead of a branch name:
git clone -c remote.origin.fetch=+<commit hash>:refs/remotes/origin/<commit hash> <repo_url> --no-checkout --progress --depth 1
git sparse-checkout init --cone
git sparse-checkout set <file list>
git checkout <commit hash>
Full workflow for cloning a single branch, choosing a commit, then checking out that specific commit... (If you already know the full sha1 hash of the commit you want, please skip ahead to the second method available in the final code block)
#Create empty git repo
mkdir repo && cd repo && git init
#add remote, configure it to track <branch>
git remote add --no-tags -t <branch> -m <branch> origin <url>
#fetch objects from remote repo
git fetch --no-write-fetch-head
#examine commits and logs to decide which one we will use
git log --oneline origin
#Once you have found the commit of interest copy the abbreviated hash or save as variable
commit=<sha1>
#rename our default branch to match remote branch
git branch -m <branch>
#set branch head to desired commit
git branch <branch> $commit
#set remote branch as upstream for <branch>
git branch -u origin <branch>
#All done time to checkout
git checkout
To optionally truncate the history of the local branch execute :
git fetch --no-write-fetch-head --depth <n> ./ <branch>
To truncate the remote branch history you can execute the following, but keep in mind that if you truncate history to a commit newer than the commit you checked out git status will tell you that you have diverged from the remote by <n> commits
git fetch --no-write-fetch-head --depth <n>
If you don't need remote tracking and already know the the full commit hash :
mkdir repo && cd repo && git init
git remote --no-tags add origin <url>
git fetch --depth 1 --no-write-fetch-head origin <sha1>
#Set default local branch (master in this case) head to <sha1>
git branch master <sha1>
git checkout
What makes this method better in my opinion is that it truly fetches only a single commit. We also avoid creating a FETCH_HEAD or ORIG_HEAD leaving our .git directory squeaky clean. This also leaves the reflog clean (with a single entry) as opposed to having two entries due to a git reset --hard commit
Without the need for remote tracking and using fetch --depth 1 it creates the smallest possible clone (shallow clone).
I use this snippet with GNU make to close any revision tag, branch or hash
it was tested on git version 2.17.1
${dir}:
mkdir -p ${@D}
git clone --recursive --depth 1 --branch ${revison} ${url} ${@} \
|| git clone --recursive --branch ${revison} ${url} ${@} \
|| git clone ${url} ${@}
cd ${@} && git reset --hard ${revison}
ls $@
git clone https://github.com/ORGANIZATION/repository.git (clone the repository)
cd repository (navigate to the repository)
git fetch origin 2600f4f928773d79164964137d514b85400b09b2
git checkout FETCH_HEAD
For single files and when the commit number is known, one can use a wget onliner:
wget https://raw.githubusercontent.com/torvalds/linux/896066ee1cf4d653057dac4e952f49c96ad16fa7/README