Firedrill:从开发人员克隆重新创建中央git存储库

Tho*_*sen 20 git

假设您有一个具有中央主git存储库的场景,开发人员和CI引擎可以从中进行克隆.即非常接近传统的非分布式版本控制系统设置,具有中央集线器和许多节点.

现在说服务器被闪电或任何其他可能导致中央存储库与其所有集中备份一起消失的东西被盗或被攻击.您剩下的就是各种克隆,幸运的是其中一个已完全更新,因此您创建了一个空白的git存储库替换服务器,用作未来的中央存储库并开始处理克隆.

完全更新的克隆使用"git branch -a"知道所有"远程/源"分支,但只有一个本地分支.(这让我担心 - 失去分支机构信息).

重新建立一个新的中央git存储库的步骤是什么,表现在任何方式,如旧的,分支机构和所有?

CB *_*ley 20

只需创建一个空的存储库,然后从完全更新的克隆中执行:

git remote add new-origin url://to/new/origin

git push --tags new-origin refs/remotes/origin/*:refs/heads/*
Run Code Online (Sandbox Code Playgroud)

显然,如果新原点与原始原点位于同一URL,则必须小心不要从原点获取.


Von*_*onC 8

首先,请不要安装gitosis:使用最新的V3 + Gitolite,一个更完整的授权层:参见" gitosis vs gitolite? "和" 你为什么需要Gitosis或Gitolite? ".

其次,您不会丢失任何分支信息.

这是同一问题的另一种方法,更长,但它说明了你如何仍然保留所有分支.

您的任何克隆可能没有所有本地分支,都是,但所有这些分支仍然在这些克隆的远程命名空间中,因为它们是从相同的(现在已经消失的)"中央"存储库克隆的.

一旦你在新的中央服务器克隆回来(作为一个简单的回购)其中一个回购,你需要的只是清理一下,你可以引用它作为你的新祝福回购.

注意:如果您无法从服务器访问本地仓库,请捆绑所说的本地仓库,并将代表该捆绑包的一个文件复制回您的服务器:您将能够从该捆绑包中克隆.
请参阅" git bundle:bundle tags and heads "以正确创建捆绑包.


精简版

# Let's re-create a bare "blessed" repo on the server
git clone --mirror /path/to/a/local/repo repo.git
# or git clone --mirror /path/to/repo.bundle repo.git

# restore the local branches
remote=origin ; for brname in `git branch -r | grep $remote | grep -v HEAD | awk '{gsub(/[^\/]+\//,"",$1); print $1}'`; do git branch --set-upstream $brname  $remote/$brname ; done

# delete the remotes branches
# (your blessed repo doesn't track anything)
remote=origin ; for brname in `git branch -r | grep $remote | grep -v HEAD | awk '{gsub(/[^\/]+\//,"",$1); print $1}'`; do git branch -r -d origin/$brname ; done

# delete the remote 'origin'
# Not needed for your blessed repo
git remote rm origin

# Let's make sure master is the current branch
# for that bare repo:
git symbolic-ref HEAD refs/heads/master
Run Code Online (Sandbox Code Playgroud)

而已.准备好出发.


长版(演示)

让我们创建一个回购协议,有4个分支:master,b1,b2,b3,每个都有自己的文件:

C:\Users\VonC\prog\git\tests>mkdir c
C:\Users\VonC\prog\git\tests>cd c
C:\Users\VonC\prog\git\tests\c>git init r1
Initialized empty Git repository in C:/Users/VonC/prog/git/tests/c/r1/.git/
C:\Users\VonC\prog\git\tests\c>cd r1
C:\Users\VonC\prog\git\tests\c\r1>echo m > m.txt && git add . && git commit -m "first commit"
[master (root-commit) 1ffe5c1] first commit
 1 file changed, 1 insertion(+)
 create mode 100644 m.txt

C:\Users\VonC\prog\git\tests\c\r1>git checkout -b b1
Switched to a new branch 'b1'
C:\Users\VonC\prog\git\tests\c\r1>echo f1 > f1.txt && git add . && git commit -m "f1 in b1"
[b1 1e64d01] f1 in b1
 1 file changed, 1 insertion(+)
 create mode 100644 f1.txt

C:\Users\VonC\prog\git\tests\c\r1>git checkout -b b2 master
Switched to a new branch 'b2'
C:\Users\VonC\prog\git\tests\c\r1>echo f2 > f2.txt git add . && git commit -m "f2 in b2"
[b2 4462b8f] f2 in b2
 1 file changed, 1 insertion(+)
 create mode 100644 f2.txt

C:\Users\VonC\prog\git\tests\c\r1>git checkout -b b3 master
Switched to a new branch 'b3'
C:\Users\VonC\prog\git\tests\c\r1>echo f3 > f3.txt && git add . && git commit -m "f3 in b3"
[b3 7ada753] f3 in b3
 1 file changed, 1 insertion(+)
 create mode 100644 f3.txt
Run Code Online (Sandbox Code Playgroud)

现在,如果我克隆r1r2,r2进入r3,是的,r3将松散分支信息:

C:\Users\VonC\prog\git\tests\c>git clone r1 r2
Cloning into 'r2'...
done.

C:\Users\VonC\prog\git\tests\c>git clone r2 r3
Cloning into 'r3'...
done.

C:\Users\VonC\prog\git\tests\c>cd r3

C:\Users\VonC\prog\git\tests\c\r3>git br -a
* b3
  remotes/origin/HEAD -> origin/b3
  remotes/origin/b3
Run Code Online (Sandbox Code Playgroud)

但在你的情况下,大部分的回购都是从受祝福的回购中克隆的直接结果.

r2拥有所有必要的分支(一个本地,4个远程跟踪分支,因为没有"本地跟踪分支 "):

C:\Users\VonC\prog\git\tests\c\r2>git br -a
* b3
  remotes/origin/HEAD -> origin/b3
  remotes/origin/b1
  remotes/origin/b2
  remotes/origin/b3
  remotes/origin/master
Run Code Online (Sandbox Code Playgroud)

如果我可以clone --mirror r2进入一个裸仓库 r4,我仍然可以获得所有分支机构.
请参阅" 之间有什么区别git clone --mirrorgit clone --bare ".

C:\Users\VonC\prog\git\tests\c>git clone --mirror r2 r4
Cloning into bare repository 'r4'...
done.

C:\Users\VonC\prog\git\tests\c>cd r4

C:\Users\VonC\prog\git\tests\c\r4>git br -a
* b3
  remotes/origin/HEAD
  remotes/origin/b1
  remotes/origin/b2
  remotes/origin/b3
  remotes/origin/master
Run Code Online (Sandbox Code Playgroud)

它的偏远仍然指向 r2

VonC@HOSTNAME ~/prog/git/tests/c/r4 (BARE:b3)
$ git remote -v
origin  C:/Users/VonC/prog/git/tests/c/r2 (fetch)
origin  C:/Users/VonC/prog/git/tests/c/r2 (push)
Run Code Online (Sandbox Code Playgroud)

但这不再需要了.
让我们确保r2(或者r1就此而言)不再可访问:

VonC@HOSTNAME ~/prog/git/tests/c/r4 (BARE:b3)
$ cd ..
VonC@HOSTNAME ~/prog/git/tests/c
$ mv r1 r1.old
VonC@HOSTNAME ~/prog/git/tests/c
$ mv r2 r2.old
VonC@HOSTNAME ~/prog/git/tests/c
$ cd r4
Run Code Online (Sandbox Code Playgroud)

现在我们可以通过将它们指向远程跟踪分支来恢复本地分支:
请参阅"将所有远程git分支跟踪为本地分支 ":

VonC@HOSTNAME ~/prog/git/tests/c/r4 (BARE:b3)
$ remote=origin ; for brname in `git branch -r | grep $remote | grep -v HEAD | awk '{gsub(/[^\/]+\//,"",$1); print $1}'`; do git branch --set-upstream $brname  $remote/$brname ; done
Branch b1 set up to track remote ref refs/remotes/origin/b1.
Branch b2 set up to track remote ref refs/remotes/origin/b2.
Branch b3 set up to track remote ref refs/remotes/origin/b3.
Branch master set up to track remote ref refs/remotes/origin/master.
Run Code Online (Sandbox Code Playgroud)

让我们master为这个裸存储库创建默认分支:
请参阅" Git:在裸存储库中更改活动分支的正确方法吗? ",以及" 如何更改Git远程HEAD指向除" master" " 之外的其他内容.

VonC@HOSTNAME ~/prog/git/tests/c/r4 (BARE:b3)
$ git symbolic-ref HEAD refs/heads/master
VonC@HOSTNAME ~/prog/git/tests/c/r4 (BARE:master)
Run Code Online (Sandbox Code Playgroud)

origin不再需要任何涉及' '的东西.
让我们摆脱远程跟踪分支:
请参阅" 删除列出的分支git branch -a "和" 删除远程分支? "

VonC@HOSTNAME ~/prog/git/tests/c/r4 (BARE:master)
$ remote=origin ; for brname in `git branch -r | grep $remote | grep -v HEAD | awk '{gsub(/[^\/]+\//,"",$1); print $1}'`; do git branch -r -d origin/$brname ; done
Deleted remote branch origin/b1 (was 1e64d01).
Deleted remote branch origin/b2 (was 4462b8f).
Deleted remote branch origin/b3 (was 7ada753).
Deleted remote branch origin/master (was 1ffe5c1).
Run Code Online (Sandbox Code Playgroud)

让我们恐慌并检查我们的本地分支是否仍然引用我们刚刚"删除"的内容:(
参见" 在git中显示每个分支的最新提交 ")

VonC@HOSTNAME ~/prog/git/tests/c/r4 (BARE:master)
$ git br -v
  b1     1e64d01 f1 in b1
  b2     4462b8f f2 in b2
  b3     7ada753 f3 in b3
* master 1ffe5c1 first commit
Run Code Online (Sandbox Code Playgroud)

是的,一切都很好.


归档时间:

查看次数:

1298 次

最近记录:

7 年,11 月 前