Git仓库的打包与还原 - bundle相关命令介绍
1、使用bundle命令打包仓库众所周知git仓库中有一个 “.git” 文件夹存储了和当前git仓库有关的所有信息。但是这个文件夹里面的文件太多了碎片文件太多影响拷贝速度如果先打包成压缩包还要多一个步骤。然而git实际上提供了打包的命令gitbundle create FILE TAGS将 “TAGS” 替换为 “–all”可以打包所有分支包括本地分支、标签、origin分支、stash分支。将 “TAGS” 替换为分支名可以打包指定分支。将 “TAGS” 替换为 “–all -10”可以打包所有分支的最后10次提交避免仓库太大产生的bundle文件太大可以用于后续的增量更新。还有更简单的办法在环境变量路径下创建一个 “bundle.bat” 文件内容如下for/f %%iin(cd)dogitbundle create%%~nxi.git--all%1然后在项目文件夹中在文件浏览器的地址栏中输入 “bundle”然后回车就可以将当前git仓库打包成于当前文件夹同名的git后缀文件。例如项目文件夹是 “repo_name”在地址栏输入 “bundle”就可以产生 “repo_name.git” 文件。如果输入 “bundle -10”就只打包最后10次提交。2、还原bundle命令打包的仓库使用 “repo_name.git” 的方法几乎完全与网络的git仓库地址一致。例如克隆命令gitclone D:\repos\repo_name.git repo_name_new但是这样操作会将 “repo_name.git” 看做一个远端所以 “repo_name” 目录下的本地仓库会在克隆后变成 “origin” 里的分支。而 “repo_name” 目录下远端分支不会进入 “repo_name_new” 目录下。使用 “–bare” 参数也不行但是可以使用 “–mirror” 参数这样会完整复制 “repo_name.git” 中记录的所有分支。但问题是 “–mirror” 模式会包含 “–bare” 参数也就是这是一个裸仓库看不到代码仓里的项目文件这还是不太方便的。所以解决方法是创建一个空文件夹然后在这个空文件夹内依次运行gitinitgitfetch D:\repos\repo_name.gitgitcheckout FETCH_HEADgitfetch D:\repos\repo_name.git *:*其中最后一条命令会将远端的分支全部覆写当前的分支也包括当前的分支。但是当前分支不能被覆写所以需要先检出到脱离分支。同时空仓库时也不能被覆写所以需要检出到一个具体的commit。所以我的做法是fetch两次第一次是为了检出到FETCH_HEAD这是一个脱离分支然后再次fetch获取所有远端分支。包括远端的本地分支、远端的远端分支、标签、和特殊分支而如果一开始不是一个空仓库不是从 git init 建立需要先检出到脱离分支gitcheckout--detach然后再做fetch覆写gitfetch D:\repos\repo_name.git *:*这个命令的做法可以将 “repo_name.git” 完全还原到最初的 “repo_name” 文件夹内的分支状态。或者可以创建一个 “bundle-clone.bat” 文件内容如下:: bundle-clone.bat echo offsetREPO_PATH%~f1md%~n1cd%~n1gitinitgitfetch %REPO_PATH%gitcheckout FETCH_HEADgitfetch %REPO_PATH% *:*然后可以快速克隆仓库bundle-clone D:\repos\repo_name.git或者可以采用和 “bundle.bat” 反向的操作创建一个 “unbundle.bat” 文件内容如下echo offfor%%iin(*.git)dosetname%%~nxigitinitgitfetch %name%gitcheckout FETCH_HEADgitfetch %name% *:*实现效果自动获取当前文件夹内的最后一个 “.git” 文件然后展开为git仓库。3、将本地仓库推送到其他远端将一个平台的仓库在不联网互通的情况下迁移到另一个平台最好的做法是使用 “git clone --mirror” 克隆然后再用 “git push origin --mirror” 推送。但是如果你下载仓库的时候不小心没有使用 “–mirror” 参数克隆也是有办法补救的。举例来说如果一个远端的仓库有 master、dev、feature 几个分支其中默认分支是 master 分支。那么如果你用 “git clone” 命令没有增加 “–mirror” 参数克隆下来的仓库分支会是master remotes/origin/master remotes/origin/dev remotes/origin/feature这时如果使用 “git push origin” 推送只会推送上去 “master” 分支。如果将追踪的远端分支一个一个 checkout 再推送那么操作繁琐。如果使用 “git push origin --mirror” 推送那也没用因为将 “remotes/origin/dev” 推送上去在远端的引用也是 “remotes/origin/dev”还是看不见。所以解决的方法是:: 推送本地分支标签gitpush URL * :: 推送本地的远端分支gitpush URL refs/remotes/origin/*:refs/heads/* :: 推送本地的远端分支标签gitpush URL refs/remotes/origin/*:refs/heads/*--tags其中第3种做法是将本地的远端分支推送到了远端的本地分支并且推送了标签。原因是你用 “git clone” 克隆下来的仓库远端分支会记录在 “refs/remotes/origin/*” 下后续检出为本地分支进行二次开发不会影响到这些记录的远端分支。然后运行这个命令就会将 “refs/remotes/origin/*” 下的分支再推送到远端的本地分支还原远端的仓库效果。或者说你克隆下来是什么样再次推上去就是什么样。4、将外网git仓库迁移到内网git仓库将上面几个步骤连起来就是迁移步骤1、从外网URL1克隆仓库和制作bundle文件gitclone URL1 REPO_NAMEcdREPO_NAMEgitbundle create REPO_NAME.git--all2、还原bundle文件和推送到内网仓库URL2cdREPO_NAMEgitinitgitfetch REPO_NAME.gitgitcheckout FETCH_HEADgitfetch REPO_NAME.git *:*gitpush URL2 refs/remotes/origin/*:refs/heads/*--tags或者可以创建一个 “push-origin.bat” 文件在文件浏览器地址栏输入后快速启用需要首先在内网服务器建立空项目echo offsetURL_BASEhttp://192.168.1.100/reposfor/f %%iin(cd)dogitpush%URL_BASE%/%%~nxirefs/remotes/origin/*:refs/heads/*--tags

相关新闻