Git 项目开发技巧:客户端间同步、暂存修改、模块化开发、备份

一、多个客户端之间的同步

有时候期望两个人之间去互相pullpush代码,那怎么做呢?

假如有同事A和B,同事A机器的IP是192.168.2.128,同事B机器的IP是192.168.2.129,现在同事A和同事B想项目同步。此时可以使用ssh协议同步,在同事A的机器上:

git remote add ubuntu_3 ssh://fly1@192.168.2.129/home/fly1/source/nginx-docs

即ubuntu_3是远程机器的名字,可以任意取,但是不能再是origin了,因为origin已经用于中央仓库了,192.168.2.129是同事B的机器IP地址,/home/lizhiyong/source/nginx-docs是同事B的repo的绝对路径。

这样可以使用git pullgit push去推送代码了,比如在同事B机器上commit一些内容,然后在同事A上使用:

git pull ubuntu_3 master    # 拉取远程ubuntu_3上的master分支代码
git push ubuntu_3 master    # 把本地的commit推送到远程ubuntu_3上的master

但是不幸的是push的时候出现了下图所示的error信息,原因是同事B的仓库不是一个裸仓库,它是有工作区间的,那么我们push的结果是不会反应在工作区间的,也即在远程仓库的目录下对应的文件还是之前的内容。
在这里插入图片描述

此时必须在同事B的机器上的.git/config文件里添加:

[receive]
        denyCurrentBranch = ignore

此时在同事B的机器上还看不到内容,但是可以看到commit记录了,需使用git reset --hard才能看到内容。

二、git stash 暂存修改

大家可能也遇到这么一种情况,你正在聚精会神地开发某个feature或者是在重构(FT-12345分支),但是突然线上冒出了一个BUG,你是那个牛逼的人,于是去解BUG,但是目前的修改怎么办才好呢?如果提交则会产生一个没有意义的commit。此时我们可以使用git stash这个神器了。保证你用了它之后会爱上它。

比如我现在FT-12345的分支上做了修改,内容如下:
在这里插入图片描述
现在要切到master分支上去修改BUG了,那在切换到master分支前我们可以暂存修改,即:

git stash   #  暂存修改
git stash pop  # 从缓存里取出修改

调用git stash后就可以使用git checkout master分支上去修复bug了,修复完了之后再git checkout FT-12345git stash pop

git stash的一些命令:

git stash   # 将工作区的修改保存到缓存区,默然取名为:
            # WIP on <branch_name> : <latest_commit_id> <latest_commit_message>
git stash save <name>     # 将工作区的修改保存到缓存区,且取名为name
git stash pop             # 取出缓存区栈顶(即最近一次)的内容,并且会删除此次pop的内容
git stash list            # 查看缓存里所有存储的修改
git stash apply stash@{X} #  取出stash里的内容,X为序号,但是不会删除stash@{X}
git stash drop stash@{X}  # 删除stash@{X}
git stash clear           # 删除缓存区里所有的记录

三、如何解决项目之间的依赖

比如我们在产品开发中,基本都会遇到这样的情况,把产品架构设计划分成了很多个模块,不同团队开发不同模块,比如源码的src目录有以下模块:

src
 |------- buffer
 |------- f-threadpool
 |------- iniconfig
 |------- intf
 |------- store
 |------- router

甚至是依赖了第三方的项目,那么我们可以使用gitsubmodule来管理这些依赖,submodule允许父项目可以有很多的独立的 Git子项目,这些子项目可以单独提交/push/pull等管理,而且父项目中的提交不会影响到子项目。这有很多好处:

  1. 把子模块单独作为一个 git 项目,他们可以独立开发,他们的错误并不会影响到父项目。
  2. 团队分模块工作在不同 git 项目上,减少了代码提交的依赖,减少了很多更新操作。

在这里插入图片描述

3.1、submodule的使用方式

添加submodule

git submodule add <url> <path>    # url是子模块的repo地址,path是在父项目中的存放路径
git submodule add git@106.52.144.219:lee/ringbuffer.git server/src/ringbuffer

添加submodule后,会发现在父项目中出现一个.gitmodules文件,文件里的内容包括:记录名字,路径和url,然后我们需要把这几个文件添加到git版本管理里:

git add .
git commit –a –m "add bloomfilter and ringbuffer submodule"
git push

3.2、如何clone submodule

一个项目仓库中并不真正保存了子模块的代码文件,他只是保存了这些配置信息而已,当我们clone仓库的时候,并不会在clone出子模块的代码,仅仅是有一个文件目录而已,里面没有任何文件,有两种方法拉取子模块的代码:

  1. git clone时加上 --recurse-submodules参数,如:git clone <url> --recurse-submodules
  2. git pull后,执行git submodule update --init --recursive

3.3、submodule的坑

仓库都是由commit记录的,是有版本的,那么在使用submodule的时候,也是一样的,仅仅是指向他的特定版本,比如我们使用git submodule status可以查看到指向的“版本”(某个commit记录),如果我们在bloomfilter这个项目上(假设有这个项目)有更新是不能自动反应到这个主repo上的,bloomfilter已经更新到了a1532ce了,但是主reposubmodule并没有指向这里,那么也就不能自动“checkout”最新代码了。那如何做?

3.3.1、如何更新submodule的内容

子模块有新的提交了,如何更新?就以上文所述,我们的bloomfilter项目已经更新了,那如何更新项目里这个submodule的版本?方法如下:

cd server/src/bloomfilter
git pull
git checkout commit-id  # 手动移动submodule的指针到某个commit-id上,
                        # 然后我们在主repo上:git submodule status,
                        # 可以看到 submodule更新了(前面有个‘+’号),
                        # 此时我们应该提交这个更新,这样别人才能获取到这个更新操作

# 提交对submodule的更新
git commit server/src/bloomfilter –m "move bloomfilter submodule to a1532ce02"
git push     # 推送更新到远程仓库

3.3.2、如何同步submodule的更新

刚刚,我们更新了submodule的内容了,也把submodule的这个“指向”更新推送到了远程仓库了,那其它的开发人员如何“同步”这种更新呢?

git pull    # 拉取最新变化
git submodule update - -remote   #更新子模块为远程项目的最新版本

3.3.3、在子模块中工作

submodule让我们看起来以为是一个仓库,我们想当然的想在里面做一些修改,可是并非如此,我们cd到该子目录后,使用git status会发现“HEAD detached at a1532ce”,这其实就告诉了我们,当前并没有处于一个分支上,并不能去提交修改,当然我们可以使用git checkout master/dev的方式切换到某个分支上,做一些修改,然后提交submodule的更新,尽管可以这么做,但是依然不建议大家如此。

HEAD detached at al532ce
nothing to commit, working directory clean

3.3.4、删除子模块

一般我们不会删除某个子模块,除非是我们的技术方案有调整,但是总之还是有可能的,此时我们可以使用git rm submodule的方式删除。

git rm 用于从 Git 版本控制中移除文件或目录。如果你想移除一个子模块,步骤稍微复杂一些,因为子模块管理了一个独立的 Git 仓库。移除子模块的简要步骤:

  1. 删除子模块条目:使用 git rm 命令来删除子模块的路径。这个命令会从索引中移除子模块,但不会删除实际的文件。

    git rm path/to/submodule
    
  2. 清理 .gitmodules 文件:手动编辑 .gitmodules 文件,删除对应的子模块条目。

  3. 更新 Git 配置:如果有必要,更新 .git/config 中对应的子模块配置,删除相关条目。

  4. 删除子模块的目录:最后,手动删除子模块的实际目录:

    rm -rf path/to/submodule
    
  5. 提交更改:提交你的更改以更新主仓库:

    git commit -m "Removed submodule"
    

四、Git备份到另一台服务器上

为了容灾,在大厂里都会对git的仓库进行备份,那如何做的呢?在解释步骤前,先介绍下场景:
在这里插入图片描述
总共有以下步骤:

  1. 设置ssh的免密登录方式:

    ssh-kengen –t rsa  # 以rsa算法生成密钥对
    vim ~/.ssh/id_rsa.pub # 把id_rsa.pub的内容拷贝后放在git仓库的/root/.ssh/authorized_keys里
    chmod 400 /root/.ssh/authorized_keys   # 在git服务器上设置文件的权限为400   
    
  2. 书写以下脚本:使用ssh协议进行git clone--mirror是拷贝镜像的意思(不能省掉,因为git仓库有很多的分支和tag信息)。
    在这里插入图片描述

  3. 通过crontab添加定时任务:

    crontab –e   # 在定时任务中添加: 0 0 * * * sh /srv/backup_remote_git.sh,然后保存
    systemctl restart cron  # 重启cron服务,如果在centos是systemctl restart crond 
    

    在这里插入图片描述

五、总结

通过本文介绍的 Git 技巧,可以更加从容地处理代码管理中的各种挑战。从有效地同步多台机器上的代码、临时保存开发中的修改、管理复杂项目中的模块依赖,到确保 Git 仓库的备份和恢复,这些方法都是提升工作效率和确保代码安全的重要手段。掌握这些技巧,不仅能让开发流程更加顺畅,还能帮助团队更好地协作和应对突发情况。
在这里插入图片描述

  • 28
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lion Long

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值