git 仓库之间迁移,并且所有分支和历史记录以及tags全部都带着 git clone 所有分支,并push到另一个repo

https://www.jianshu.com/p/05d32b67c958

在多台电脑使用git管理开发分支的时候,会出现这样的情况。电脑A创建了分支1,并且push上了远程仓库。

电脑B本地clone仓库默认只会clone下master分支,而其他电脑A推送的分支是不会默认同步下来的。

那么如何同步呢?

 

四种方法:

第一种

查看电脑B本地仓库的分支

git branch

首先,先来看看上面描述的情况,电脑B查看本地的所有分支,如下:

 

$ git branch
* master

可以看到clone下来的远程仓库并不会将所有分支都clone下来。

查看A本地和远程仓库的所有分支

git branch -a

上面看了本地仓库只有master分支,那么怎么查看本地和远程仓库的所有分支呢?如下

root@localhost:~/word/git/centos-logos(master○) # git branch -a
  remotes/origin/c4
  remotes/origin/c5
  remotes/origin/c5-plus
  remotes/origin/c6
  remotes/origin/c6-plus
  remotes/origin/c7
  remotes/origin/c8
  remotes/origin/c8-sig-artwork

从这里已经可以知道远程有哪些分支可以提供本地去同步了,目前是没有一个可以供本地同步的,都是远程分支。那么如果单独查看远程的分支呢?

查看远程仓库的分支

git branch -r

单独直接查看远程仓库的所有分支如下:

root@localhost:~/word/git/centos-logos(master○) # git branch -r
  origin/c4
  origin/c5
  origin/c5-plus
  origin/c6
  origin/c6-plus
  origin/c7
  origin/c8
  origin/c8-sig-artwork

其实用起来还没有直接 git branch -a 查看所有来得清晰。下一步看看如何同步远程分支

同步远程分支

  • git fetch 将本地分支与远程保持同步
  • git checkout -b 本地分支名x origin/远程分支名x  拉取远程分支并同时创建对应的本地分支

首先同步所有远程分支,如下:
 

git branch -r | grep -v '\->' | while read remote; do git branch --track "${remote#origin/}" "$remote"; done

 

root@localhost:~/word/git/centos-logos(master○) # git branch -r | grep -v '\->' | while read remote; do git branch --track "${remote#origin/}" "$remote"; done
Branch c4 set up to track remote branch c4 from origin.
Branch c5 set up to track remote branch c5 from origin.
Branch c5-plus set up to track remote branch c5-plus from origin.
Branch c6 set up to track remote branch c6 from origin.
Branch c6-plus set up to track remote branch c6-plus from origin.
Branch c7 set up to track remote branch c7 from origin.
Branch c8 set up to track remote branch c8 from origin.
Branch c8-sig-artwork set up to track remote branch c8-sig-artwork from origin.
root@localhost:~/word/git/centos-logos(master○) # git br -a                                                                                                           127 ↵
  c4
  c5
  c5-plus
  c6
  c6-plus
  c7
  c8
  c8-sig-artwork
  remotes/origin/c4
  remotes/origin/c5
  remotes/origin/c5-plus
  remotes/origin/c6
  remotes/origin/c6-plus
  remotes/origin/c7
  remotes/origin/c8
  remotes/origin/c8-sig-artwork
root@localhost:~/word/git/centos-logos(master○) #

 此时已经有本地分支了,而且也和远程分支关联了

将本地所有分支与远程保持同步 git fetch --all

最后拉取所有分支代码 git pull --all

 然后修改远程分支地址

git remote set-url origin ssh://git@10.10.3.189:2222/x86/centos-logos.git

提交所有本地分支到修改后的远程分支以及tags

git push -u origin --all
git push -u origin --tags

 

第二种方法git clone 所有分支,并push到另一个repo

 

啥,github的私人项目免费了??赶紧把gitlab的私人项目迁移出来压压惊。这要求我们,首先将所有的分支从gitlab下载到本地,并且是本地分支,然后推送到github上去。但是,直接git clone的话,查看本地分支,竟然只有是master分支?我的天,但是我想要的是推送所有的分支到github上。咋整?
git clonegit branch为啥只看到了一个本地分支master。难道不会把所有分支都clone下来?
我们查看git branch -a

* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/branch1
  remotes/origin/branch2

但是,如果我们直接切换分支git checkout branch1
显示

分支 branch1 设置为跟踪来自 origin 的远程分支 branch1。
切换到一个新分支 'branch1'
  • 此时,查看本地分支git branch
master
*branch1

啥,怎么这么诡异。为啥我能切换到远程分支?其实是这样的,git clone会将所有的远程分支都下载下来,但是就是把远程的master会变成本地的master分支。其他的远程分支,名字仍旧是远程分支,没有重新命名。一个个checkout?如果我项目有几十个分支,那我不要累死?? 

正确的解决方法:

将远端分支全部变成本地分支

首先将项目的所有分支clone下来,并且变成本地分支

mkdir centos-logos
cd centos-logos
git clone --bare https://git.centos.org/rpms/centos-logos .git   
git config --unset core.bare
git reset --hard

上面的意思是,首先随便建立一个文件夹centos-logos,然后在里面只将https://git.centos.org/rpms/centos-logos的.git文件夹拷贝下来!此时,centos-logos里面还是没有任何repo的文件,只有一个隐藏文件夹.git。然后解除core.bare模式,然后再恢复所有的repo文件。此时,所有的xxx的所有的分支都是本地分支了!

将本地分支全部推到远端

将所有的分支都推送到github上去
首先新建一个github项目。比如是yyy

别看github的提示了,完全在扯。
原始github教你的迁移方式:

git remote add origin ssh://git@10.10.3.189:2222/x86/centos-logos.git
git push -u origin master

这是干嘛,首先直接git remote add origin  ssh://git@10.10.3.189:2222/x86/centos-logos.git肯定会出错,因为你git clone下载的项目,其相应的远端分支remotes/origin是对应的是gitlab/xxx的位置。其次,这里git push -u origin master只是将当前分支推送到远端的master分支啊,这样github只会有一个master分支!

正确方法

git remote rename origin old_origin
git remote add origin ssh://git@10.10.3.189:2222/x86/centos-logos.git
git push -u origin --all
git push -u origin --tags

或者

git remote set-url origin ssh://git@10.10.3.189:2222/x86/centos-logos.git
git push -u origin --all
git push -u origin --tags

第一条命令,因为当前的默认remote的origin是gitlab的那个xxx,那么肯定要放弃那个,直接随便改个名字就行,比如这里改成old_origin。然后,再添加新的remote origin。然后,我们将所有的branch推到github上去,这里是用--all,不是master。最后一句话,是将tags也推上去。
 

第三种方法git clone 所有分支,并push到另一个repo

先了解一下概念

Git 工作区、暂存区和版本库


基本概念

我们先来理解下 Git 工作区、暂存区和版本库概念:

  • 工作区就是你在电脑里能看到的目录。
  • 暂存区英文叫 stage 或 index。一般存放在 .git 目录下的 index 文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
  • 版本库:工作区有一个隐藏目录 .git,这个不算工作区,而是 Git 的版本库。

下面这个图展示了工作区、版本库中的暂存区和版本库之间的关系:

 

  • 图中左侧为工作区,右侧为版本库。在版本库中标记为 "index" 的区域是暂存区(stage/index),标记为 "master" 的是 master 分支所代表的目录树。

  • 图中我们可以看出此时 "HEAD" 实际是指向 master 分支的一个"游标"。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。

  • 图中的 objects 标识的区域为 Git 的对象库,实际位于 ".git/objects" 目录下,里面包含了创建的各种对象及内容。

  • 当对工作区修改(或新增)的文件执行 git add 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。

  • 当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。

  • 当执行 git reset HEAD 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。

  • 当执行 git rm --cached <file> 命令时,会直接从暂存区删除文件,工作区则不做出改变。

  • 当执行 git checkout . 或者 git checkout -- <file> 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。

  • 当执行 git checkout HEAD . 或者 git checkout HEAD <file> 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。

 

事故现场

有些时候,当我们使用 git checkout <branchname>命令切换分支的时候,有时会切换失败,然后出现以下的提示信息

root@koji:~/centos-release(c7○) # git co c8                                                                          
error: Your local changes to the following files would be overwritten by checkout:
	rootfs-expand
	update-boot
Please, commit your changes or stash them before you can switch branches.
Abortin
提示信息说的很清楚,
当前分支有未跟踪的文件,checkout 命令会覆盖它们,请缓存( stash )或者提交( commit )。

 先说解决方法吧

这个时候,你有两种选择:

###1.未跟踪文件的内容改动很重要,保存修改

//第一种方式 存到暂存区
git add.
git stash 
//取出的时候使用 
git stash pop

//第二种方式 发起一个commit 存到提交历史
git add.
git commit -m "commit message"

###2.未跟踪文件的内容改动不重要,放弃修改

这个有两种办法,清除修改和强制切换分支

推荐做法:清除未跟踪文件

git clean n  //这个是清除文件预览
git clean -f //强制清除文件
git clean -dnx

强制切换分支

强制切换分支命令如下,结果同提示说的那样,会直接覆盖未跟踪的文件。这个方式我觉得很是粗暴,我们日常切换的时候,还是不要使用 -f 强制切换,没有覆盖提示,很容易发生文件修改丢失,但是我们自己不知道。

root@koji:~/centos-release(c7○) # git co -f c8                                                                                                                          1 ↵
Branch c8 set up to track remote branch c8 from origin.
Switched to a new branch 'c8'

 

git 的本地版本管理有三个部分

名称说明
工作区(Working Directory)我们直接编辑的文件部分
暂存区(Staged Snapshot)文件执行 git add .后存的地方
版本库区 (Commit History)文件执行 git commit .后存的地方

 

图片来自网络 

当我们执行 checkout 操作的时候,git 会检查工作区是否存在未跟踪文件,这就是我们上面当执行 checkout 的时候出现错误提示的原因。 

[root@ecs-s6-large-2-linux-20200707122301 ]# git init aa
[root@ecs-s6-large-2-linux-20200707122301 aa]# ls .git/
branches  config  description  HEAD  hooks  info  objects  refs
[root@ecs-s6-large-2-linux-20200707122301 aa]# touch a.txt
[root@ecs-s6-large-2-linux-20200707122301 aa]# ls .git/
branches  config  description  HEAD  hooks  info  objects  refs
只有add的时候才进入版本库中的暂存区(.git/index),之上都在工作区中
[root@ecs-s6-large-2-linux-20200707122301 aa]# git add a.txt 
[root@ecs-s6-large-2-linux-20200707122301 aa]# ls .git/
branches  config  description  HEAD  hooks  index  info  objects  refs
[root@ecs-s6-large-2-linux-20200707122301 aa]# vim .git/info/
[root@ecs-s6-large-2-linux-20200707122301 aa]# vim .git/index 
commit之后就从暂存区到版本库了(.git)
[root@ecs-s6-large-2-linux-20200707122301 aa]# git commit -a -m "init"
[master (root-commit) dc00bcd] init
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a.txt
[root@ecs-s6-large-2-linux-20200707122301 aa]# ls .git/
branches  COMMIT_EDITMSG  config  description  HEAD  hooks  index  info  logs  objects  refs

git clone --mirror 和  git clone --bare区别自行去查阅(两者类似,但有区别。mirror属于完全备份更彻底点,跟踪也有了。)

[root@ecs-s6-large-2-linux-20200707122301 aaa]# git clone --mirror  https://git.centos.org/rpms/389-ds-base
Cloning into bare repository '389-ds-base.git'...
remote: Counting objects: 1149, done.
remote: Compressing objects: 100% (1082/1082), done.
remote: Total 1149 (delta 66), reused 948 (delta 0)
Receiving objects: 100% (1149/1149), 2.89 MiB | 897.00 KiB/s, done.
Resolving deltas: 100% (66/66), done.
[root@ecs-s6-large-2-linux-20200707122301 aaa]# 
[root@ecs-s6-large-2-linux-20200707122301 aaa]# ls
389-ds-base.git  centos-git-mirror.sh  forks  rpms
[root@ecs-s6-large-2-linux-20200707122301 aaa]# ls 389-ds-base.git/
branches  config  description  HEAD  hooks  info  objects  packed-refs  refs

在自己的gitlab私有的仓库中创建group(组),如test,然后git push --mirror

[root@localhost centos-release.git]# git push --mirror  ssh://git@10.10.3.104:2222/test/centos-release.git
Counting objects: 380, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (202/202), done.
Writing objects: 100% (380/380), 107.01 KiB | 0 bytes/s, done.
Total 380 (delta 106), reused 380 (delta 106)
remote: Resolving deltas: 100% (106/106), done.
remote: 
remote: The private project test/centos-release was successfully created.
remote: 
remote: To configure the remote, run:
remote:   git remote add origin ssh://git@10.10.3.104:2222/test/centos-release.git
remote: 
remote: To view the project, visit:
remote:   http://10.10.3.104:9312/test/centos-release
remote: 
To ssh://git@10.10.3.104:2222/test/centos-release.git
 * [new branch]      c7 -> c7
 * [new branch]      c7-sig-altarch -> c7-sig-altarch
 * [new branch]      c8 -> c8
 * [new branch]      refs/pull/10/head -> refs/pull/10/head
 * [new branch]      refs/pull/4/head -> refs/pull/4/head
 * [new branch]      refs/pull/5/head -> refs/pull/5/head
 * [new branch]      refs/pull/6/head -> refs/pull/6/head
 * [new branch]      refs/pull/7/head -> refs/pull/7/head
 * [new branch]      refs/pull/8/head -> refs/pull/8/head
 * [new branch]      refs/pull/9/head -> refs/pull/9/head

第四种方法

gitlab-mirror同步方式

 

仅三行命令即可完成:

root@koji:/home/8/rpms/sources/aa # git clone --bare https://git.centos.org/rpms/389-ds-base.git 

root@koji:/home/8/rpms/sources/aa # cd 389-ds-base.git

root@koji:/home/8/rpms/sources/aa # git push --mirror http://10.10.3.104:9312/rpms/389-ds-base.git

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值