簡體   English   中英

如何克隆具有特定修訂/變更集的 git 存儲庫?

[英]How to clone git repository with specific revision/changeset?

我如何克隆具有特定修訂版的 git 存儲庫,就像我通常在 Mercurial 中所做的那樣:

hg clone -r 3 /path/to/repository
$ git clone $URL
$ cd $PROJECT_NAME
$ git reset --hard $SHA1

再次回到最近的提交

$ git pull

更新 2Git 2.5.0 開始,可以在服務器端使用配置變量uploadpack.allowReachableSHA1InWant啟用下面描述的功能,這里是GitHub 功能請求GitHub 提交啟用此功能 請注意,某些 Git 服務器默認啟用此選項,例如 Bitbucket Server 從5.5+ 版本開始啟用它。 有關如何激活配置選項的示例,請參閱Stackexchange 上的答案

更新 1對於 Git 版本1.7 < v < 2.5使用 git clone 和 git reset,如Vaibhav Bajpai 的回答中所述

如果您不想獲取完整的存儲庫,那么您可能不應該使用clone 你總是可以使用 fetch 來選擇你想要獲取的分支。 我不是汞專家,所以我不知道-r的細節,但在 git 中你可以做這樣的事情。

# make a new blank repository in the current directory
git init

# add a remote
git remote add origin url://to/source/repository

# fetch a commit (or branch or tag) of interest
# Note: the full history up to this commit will be retrieved unless 
#       you limit it with '--depth=...' or '--shallow-since=...'
git fetch origin <sha1-of-commit-of-interest>

# reset this repository's master branch to the commit of interest
git reset --hard FETCH_HEAD

要在特定分支或標簽上克隆一個特定的提交,請使用:

git clone --depth=1 --branch NAME https://github.com/your/repo.git

不幸的是, NAME只能是分支名稱或標簽名稱(不是提交 SHA)。

省略--depth標志以下載整個歷史記錄,然后檢出該分支或標簽:

git clone --branch NAME https://github.com/your/repo.git

這適用於最新版本的 git (我用版本2.18.0 )。

克隆一個 git 存儲庫,恰當地,克隆整個存儲庫:沒有辦法只選擇一個修訂版進行克隆。 但是,一旦您執行git clone ,您就可以通過執行checkout <rev>來檢出特定的修訂checkout <rev>

如果您的意思是要獲取從開始到特定點的所有內容,那么 Charles Bailey 的答案是完美的。 如果您想反向操作並檢索從當前日期返回的歷史子集,您可以使用git clone --depth [N]其中 N 是您想要的歷史轉數。 然而:

- 深度

創建一個將歷史記錄截斷為指定修訂數量的淺層克隆。 淺層存儲庫有很多限制(你不能從它克隆或獲取,也不能從它推入或推入),但如果你只對一個歷史悠久的大型項目的近期歷史感興趣,並且想要將修復作為補丁發送。

總結一下(git v. 1.7.2.1):

  1. 在你想要倉庫的地方做一個常規的git clone (讓所有的東西都是最新的——我知道,不是想要的,我們正在那里)
  2. git checkout <sha1 rev>你想要的 rev
  3. git reset --hard
  4. git checkout -b master

您可以簡單地使用git checkout <commit hash>

在這個序列中

bash git clone [URLTORepository] git checkout [commithash]

提交哈希看起來像這樣“45ef55ac20ce2389c9180658fdba35f4a663d204”

TL;DR - 只需在源存儲庫中針對要克隆到的提交創建一個標簽,並在 fetch 命令中使用該標簽。 您可以稍后從原始存儲庫中刪除標簽以進行清理。

好吧,它是 2014 年,看起來 Charles Bailey 從 2010 年開始接受的答案現在已經完全過時了,大多數(全部?)其他答案都涉及克隆,許多人希望避免這種情況。

以下解決方案實現了 OP 和許多其他人正在尋找的東西,這是一種創建存儲庫副本的方法,包括歷史記錄,但僅限於某個提交。

以下是我在 git 版本 2.1.2 中用於將本地存儲庫(即另一個目錄中的存儲庫)克隆到某個點的命令:

# in the source repository, create a tag against the commit you want to check out
git tag -m "Temporary tag" tmptag <sha1>

# create a new directory and change into that directory
cd somewhere_else;mkdir newdir;cd newdir

# ...and create a new repository
git init

# add the source repository as a remote (this can be a URL or a directory)
git remote add origin /path/to/original/repo

# fetch the tag, which will include the entire repo and history up to that point
git fetch origin refs/tags/tmptag

# reset the head of the repository
git reset --hard FETCH_HEAD

# you can now change back to the original repository and remove the temporary tag
cd original_repo
git tag -d tmptag

希望這個解決方案還能再工作幾年! :-)

無需下載整個歷史記錄,也無需調用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

對於 CB Baileys 的回答,這有一個缺點,即您仍然會下載 1 個不必要的修訂版。 但它在技術上是一個git clone (OP 想要的),它不會強迫您下載某個分支的整個歷史記錄。

使用上述答案中的 2 個( 如何使用特定修訂版/變更集克隆 git 存儲庫以及如何使用特定修訂版/變更集克隆 git 存儲庫? )幫助我想出了一個確定性。 如果您想克隆到某個點,那么該點必須是一個標簽/分支,而不僅僅是一個 SHA,否則 FETCH_HEAD 會被混淆。 在 git fetch 集之后,如果您使用分支或標簽名稱,則會收到響應,如果您僅使用 SHA-1,則不會收到響應。
這就是我所做的:-從實際來源創建完整存儲庫的完整工作克隆

cd <path to create repo>
git clone git@<our gitlab server>:ui-developers/ui.git 

然后創建一個本地分支,這很有趣

git checkout 2050c8829c67f04b0db81e6247bb589c950afb14
git checkout -b origin_point

然后創建我的新空白 repo,以我的本地副本作為其來源

cd <path to create repo>
mkdir reduced-repo
cd reduced-repo
git init
git remote add local_copy <path to create repo>/ui
git fetch local_copy origin_point

那時我得到了這個回應。 我注意到它是因為如果你使用 SHA-1 代替上面的分支,什么都不會發生,所以響應意味着它有效

/var/www/html/ui-hacking$ git fetch local_copy origin_point
remote: Counting objects: 45493, done.
remote: Compressing objects: 100% (15928/15928), done.
remote: Total 45493 (delta 27508), reused 45387 (delta 27463)
Receiving objects: 100% (45493/45493), 53.64 MiB | 50.59 MiB/s, done.
Resolving deltas: 100% (27508/27508), done.
From /var/www/html/ui
 * branch            origin_point -> FETCH_HEAD
 * [new branch]      origin_point -> origin/origin_point

現在在我的情況下,我需要把它放回 gitlab,作為一個新的 repo,所以我做了

git remote add origin git@<our gitlab server>:ui-developers/new-ui.git

這意味着我可以使用git --git-dir=../ui/.git format-patch -k -1 --stdout <sha1> | git am -3 -k從 origin_point 重建我的倉庫git --git-dir=../ui/.git format-patch -k -1 --stdout <sha1> | git am -3 -k git --git-dir=../ui/.git format-patch -k -1 --stdout <sha1> | git am -3 -k遠程挑選櫻桃然后使用git push origin將整個地塊上傳回新家。

希望能幫助某人

我的版本是接受和最受好評的答案的組合。 但它有點不同,因為每個人都使用 SHA1 但沒有人告訴你如何獲得它

$ git init
$ git remote add <remote_url>
$ git fetch --all

現在你可以看到所有的分支和提交

$ git branch -a
$ git log remotes/origin/master <-- or any other branch

最后你知道所需提交的 SHA1

git reset --hard <sha1>

我將此代碼段與 GNU make 一起使用來關閉任何修訂標記、分支或哈希

它在 git 版本 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 $@




# 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> 

如果未在服務器端設置uploadpack.allowReachableSHA1InWant=true ,則無法獲得沒有歷史記錄的修訂版,而您可以為其創建標簽並克隆特殊標簽。

克隆單個分支的完整工作流程,選擇一個提交,然后檢查該特定提交...此方法需要 git 版本 2.28.0 或更高版本才能使用選項--no-write-fetch-head ,已使用版本 2.35 進行測試。 3. (如果您已經知道所需提交的完整 sha1 hash,請跳至最終代碼塊中提供的第二種方法)

#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

要選擇性地截斷本地分支的歷史記錄,請執行:

git fetch --no-write-fetch-head --depth <n> ./ <branch>

要截斷遠程分支歷史記錄,您可以執行以下操作,但請記住,如果您將歷史記錄截斷為比您簽出的提交更新的提交, git status將告訴您您已經從遠程分支<n>提交

git fetch --no-write-fetch-head --depth <n>

如果您不需要遠程跟蹤並且已經知道完整的提交 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

在我看來,使這種方法更好的是它真正只獲取一次提交。 我們還避免創建 FETCH_HEAD 或 ORIG_HEAD,使我們的 .git 目錄干凈利落。 這也使 reflog 保持干凈(只有一個條目),而不是由於git reset --hard commit無需遠程跟蹤和使用fetch --depth 1它創建盡可能小的克隆(淺克隆) .

我能夠使用 git clone --config 選項完成此操作,這是我從以下答案中了解到的: https : //stackoverflow.com/a/43759576/1330650

我的場景涉及 Azure DevOps 管道中的稀疏結帳,我需要使用提交哈希而不是分支名稱克隆存儲庫。 clone 命令不接受提交哈希作為參數。 解決方法是設置一個包含 refspec 的配置變量 (-c),因為該 refspec 可以使用提交哈希而不是分支名稱:

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>
mkdir linux-4.3.20151106
cd linux-4.3.20151106/
git init
git fetch git@github.com:torvalds/linux.git 9154301a47b33bdc273d8254c407792524367558

error: unknown option `no-write-fetch-head'        
usage: git fetch [<options>] [<repository> [<refspec>...]]   or: git fetch [<options>] <group>                                      
   or: git fetch --multiple [<options>] [(<repository> | <group>)...]   or: git fetch --all [<options>]       



 git --version
git version 2.17.1

export https_proxy=http://192.168.1.3:1080;export http_proxy=http://192.168.1.3:1080
add-apt-repository ppa:git-core/ppa
apt update
apt-get install --only-upgrade git

 git --version
git version 2.38.0


 git fetch git@github.com:torvalds/linux.git 9154301a47b33bdc273d8254c407792524367558 --no-write-fetch-head --depth=1 
remote: Enumerating objects: 54692, done.
remote: Counting objects: 100% (54692/54692), done.
remote: Compressing objects: 100% (50960/50960), done.
remote: Total 54692 (delta 3828), reused 29210 (delta 2966), pack-reused 0
Receiving objects: 100% (54692/54692), 147.35 MiB | 2.85 MiB/s, done.
Resolving deltas: 100% (3828/3828), done.
 


git branch master 9154301a47b33bdc273d8254c407792524367558


git checkout
 

git clone https://github.com/ORGANIZATION/repository.git (克隆存儲庫)

cd repository (navigate to the repository)

git fetch origin 2600f4f928773d79164964137d514b85400b09b2

git checkout FETCH_HEAD

對於單個文件,當提交號已知時,可以使用 wget 在線工具:

wget https://raw.githubusercontent.com/torvalds/linux/896066ee1cf4d653057dac4e952f49c96ad16fa7/README

如何克隆具有特定修訂版的git存儲庫,就像我通常在Mercurial中所做的那樣:

hg clone -r 3 /path/to/repository

您是否聽說過Rigidhackpro是偽造的黑客,曾對我姐姐進行過嘗試。 我可以向任何人開出的唯一真正合法的黑客專家是fasthackresults @ Gmail,com他是技術和信用評分操作的專家

git clone -o <sha1-of-the-commit> <repository-url> <local-dir-name>

git使用單詞origin而不是眾所周知的revision

以下是手冊$ git help clone的片段

--origin <name>, -o <name>
    Instead of using the remote name origin to keep track of the upstream repository, use <name>.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM