代码版本管理 | Python 程序员也应该会的 Git 进阶操作

配置多个远端仓库

# 查看当前远程仓库地址
git remote -v

地址后面有一个括号里面有 push 和 fetch 两种,当我们执行 git push 时候他会调用对应 push 地址,同样当我们执行命令 git featch 的时候则会调用 fetch 地址;当拉去代码之后默认情况下会产生一个远程仓库 origin ,并 且对应的 push 地址也只有一个

如果我们想把代码往多个代码托管平台推送只需要添加一个远程地址即可

git remote add [远程仓库自定义名字] [git 仓库地址]

接下来将代码推送至刚刚添加的远程仓库上

git push [远程仓库自定义名字]

我们想推送代码至新添加的远程仓库的话,就是用上面的命令

但是我们想使用 git push 推送至新添加的远程仓库的话应该怎么操作

使用 -u 参数来修改默认的远程仓库

git push -u [[远程仓库自定义名字]]

如果想一条命令推送至多个仓库怎么操作?

git remote set-url --add origin [远程仓库地址]

这个时候再使用

git remote -v
# 这个时候 origin 就会有三个地址,两个 push 一个 fetch

本地仓库覆盖远程仓库

直接删除代码可以通过查看记录看到代码的记录

# 查看提交记录
git log
# 找到提交敏感信息前的 hash
git reset [hash 值]
# git push提交代码会报错,因为提交的版本号落后与远程版本
git push -f # 强制覆盖

单独回滚代码不改记录

使用 reset 可以回滚代码,但是仓库设置了保护分支就没办法强制调教

所以这里使用 revert 可以回滚指定的版本的代码

需要注意的是,在使用 revert 去恢复某个版本代码时, Git 只会撤销指定版本的代码,而不是指定版本后的所有版本

将工作区的代码暂存起来

1.  git stash 暂存当前工作区的改动
# 讲代码分支切换过去,做你想要的操作
# 操作完成后,切换会你的开发分支
2.  git stash apply { 暂存区编号 } 不填编号恢复上一次暂存的改动,填了恢复指定暂存记录
3.  git stash list 查看暂存区列表

大版本迭代未完成,要发小版本,如何操作?

我们可以先从 develop 分支切换到 test 分支中去,然后从 test 分支基础 上中新建一个 tmp 临时开发分支,在 tmp 分支中开发功能。

当开发完成之后再切回 test 分支,使用 git rebase 命令将 tmp 分支的提交记录复制到 test 分支中去,这样就可以交给测试人员测试后发布新版本了。

不过为了避免将来 develop 分支的版本开发完成后,与 test 分支合并产生 代码冲突问题,我们还需要切换到 develop 分支中,同样使用 git rebase 命令将 tmp 分支上提交的版本复制过来,这样就保障了临时任务可以提前单独发布到线上去,还不会将来产生代码冲突问题。

# 切换 test 
git checkout test
# 新建一个小版本分支
git checkout -b tmp_bug
# 开发功能,修改bug后,切换回 test 分支
git checkout test
# 将 tmp_bug 分支中的提交记录复制到当前分支
git rebase tmp_bug

避免代码冲突

假设在 tmp_bug 中修改了 develop 分支的文件代码,之后合并时会出现冲突,如何避免?

# 切换 develop 分支
git checkout develop
# 将 tmp_bug 分支的版本复制过来
git rebase tmp_bug

1、新建一个临时分支,在临时分支中开发

2、回到 test 分支中,将临时分支的版本记录复制过来,单独发布上线

3、回到 develop 分支中,将临时分支的版本记录复制过来,避免后续与 test 分支产生代码冲突

多人代码冲突处理

与远程代码冲突

# 修改冲突文件,然后使用下面的命令提交
git commit -a 

rebase 冲突

# 提交冲突,删除冲突文件,然后继续提交
git add . && git rebase --continue
# 会提示我们没有改动
# 这里出现没有改动,是因为 git rebase 命令先将自己的差异版本记录拿到一边去,然后将 develop 分支的改动复制进来,然后再将自己差异的版本记录插入到末尾
# 当出现上述提示时,我们可以使用 git rebase --skip 命令进行忽略
git rebase --skip

暂存区冲突

# 将代码 git stash 之后,继续修改了文件,并提交到了仓库,这个时候使用 git stash apply 恢复,这个时候只要修改冲突文件为需要的部分即可

1、git merge 和 git pull 命令导致的冲突,处理完冲突后使用 git commit -a ;

2、git rebase 命令导致的冲突,处理完冲突之后使用 git rebase --continue 或 git rebase --skip ;

3、git stash apply 命令导致的冲突,处理完冲突之后使用 git add . 即可。

历史记录清理

只克隆最后一个版本记录 - 本地仓库

git clone [git path] 文件夹 --depth==1

清空版本记录 - 远程仓库

# 假如远程服务器的 develop 版本很多
# 切换 develop 分支
git checkout develop
# 创建一个特殊的新分支
#加上一个 --orphan 参数,加上这个参数之后创建的分支有点特殊,他只有最后一个版本,而不是把所有的版本都复制过来,严格来说创建出来的不是分支,但很像分支
git checkout --orphan new_branch
# 将这个分支下的所有内容都添加
git add -A && git status
# 内容全部提交
git commit -m "new version"
# 然后将 develop 分支删除
git branch -D develop
# 删除后将 new_branch 分支重命名为 develop
git branch -m develop
# 使用 git push -f 强制推送至远程仓库
# 有些仓库有 master  分支保护,不允许强制 push ,需要在远程仓库项目里暂时把项目保护关掉才能推送
git push -f origin develop

清理大文件

现在需要找出大文件的对应 hash 值,这里我们找出前 5 个为例

git verify-pack -v .git/objects/pack/pack-*.idx | sort -k 3 -g | tail -5

根据 hash 值找到对应大文件名

# git rev-list --objects --all | grep [hash 值]
git rev-list --objects --all | grep 6ba572e5b6b9237a29bd883595e82f5a48e62a66

我们要清除这个文件在所有历史中的记录,并强制刷新到所有分支,这里推送到远程仓库需要有强制推送权限。执行删除 vendor.zip 文件,在所有历史版本中的记录

git filter-branch --index-filter 'git rm --cached --ignore-unmatch vendor.zip'

在上面的命令中我们删除了文件,但是在 Git 的 repo 里面还记录了这些文件的信息,这些信息也会占用一定的空间,我们继续清除这些信息,并收回存储空间

rm -rf .git/refs/original/  && git reflog expire --expire=now --all

清除多余信息之后,我们需要重新建立文件与 Git 仓库的关联关系

git fsck --full --unreachable

重新压缩代码,减少仓库体积

git repack -A -d

通过 Git 的 GC 清理一些垃圾数据

git gc --aggressive --prune=now

让远程仓库也清理,可以强制推送到远程仓库

git push --force origin master

搭建 gitlab 服务器

安装 docker,下载镜像

docker pull gitlab/gitlab-ce

建立映射文件夹

mkdir -p ~/config/gitlab/config
mkdir -p ~/config/gitlab/logs
mkdir -p ~/config/gitlab/data

运行容器

docker run --detach --publish 8443:443 --publish 8090:80 --publish 2222:22 --name gitlab --restart always -v /Users/song/config/gitlab/config:/etc/gitlab -v
/Users/song/config/gitlab/logs:/var/log/gitlab -v /Users/song/config/gitlab/data:/var/opt/gitlab gitlab/gitlab-ce
(完)