[版本管理] Git 学习沉淀

Git 学习沉淀

1. 概述

使用了Git作为项目的管理工具也有些日子了,Git作为一个很Nice的工具,其有繁杂的命令,但实际上在项目中使用且实用的命令并不多,或者说并不难掌握,只是有些命令是组合套路,容易遗忘。

所以,本篇主要是记录一些学习Git中的笔记,便于日后翻阅,拾起来。

2. 基本知识

首先,使用的Git作为版本管理的工作目录(项目根目录)都有一个隐藏文件: .git,
这个隐藏文件是Git工具的核心,它保存了项目所有的变动。

  • Git 初始化配置的套路

    查看Git的所有的初始化配置

    $ git config --list

    查看所有的初始化配置信息会有重复的数据(分为全局配置和局部配置),不利于我们得到真正想要的信息。

    所以,我们可以查看Git的单个初始化配置(类似于继承重载)

    $ git config user.name

    配置Git的关键信息,user.name & user.email

    $ git config --global user.name “wxsmile”
    $ git config --global user.email “wxsmile@nb.com”

  • 理解Git中的几种状态

    Untracked files : 未跟踪的文件
    changes to be commited : 可以提交的改动
    changes not staged for commit : 不可提交的改动
    commited : 已提交的改动

3. 上手

  • 一次简单的Git流程

    $ git init
    $ git add .
    $ git commit -m “commit message”
    $ git push

  • 团队中的一次简单Git流程

    git clone [url] [alias name]

    $ git clone https://github.com/…/git-project.git myproject
    $ git add .
    $ git commit
    $ git pull
    $ git push

  • push的本质

    直观上,push是将本地的commit上传到中央仓库,用本地的内容覆盖远端的内容。

    实质上,push是将当前branch以及其上所有的commits一并上传。

    一般操作:

    $ git checkout feature-some
    $ git push
    $ git push origin master
    $ git push origin develop

  • merge的本质

    merge就是,把目标commit所属的分支上的所有commits应用到当前分支

    一次简单的合并操作

    $ git checkout -b feature-some
    $ git add.
    $ git commit
    $ git checkout master
    $ git add.
    $ git commit
    $ git merge feature-some

    一次简单的快速前移fast-forward(ff)

    $ git checkout -b new-feature
    $ git add.
    $ git commit
    $ git checkout master
    $ git merge new-feature

  • add的本质

    一般操作

    $ git add a.txt
    $ git commit

    查看commit的简要统计

    $ git log --stat

    a.txt | 1+
    1 file changed, 1 insertion(+)

    本质上是a.txt文件的内容变动记录用于被提交,而不是文件名。

    对比工作目录和暂存区

    $ git diff
    $ git diff staged

4. 一些有点难度但是常用的东西

  • 优雅的修正上一个糟糕的commit, 类似如下

    $ git add a.txt
    $ git commit -m “买了女装” (一次糟糕的提交)
    修改a.txt…
    $ git add a.txt
    $ git commit --amend (优雅的修复上一次糟糕的提交)

    值得注意的是,这种操作不是直接修改原commit的内容,而是会产生一个新的commit,然后覆盖原来糟糕的commit。

  • 修正上上次的糟糕提交,用到 rebase -i [目标commit]

    这种操作叫做:交互式变基

    譬如该分支倒数第二个commit是一个糟糕的commit

    $ git rebase -i head^^

    执行之后,跳到如下编辑界面:
    rebase -i 编辑
    主要看里面的commands, 看英文说明,已经说得很清楚了,这里将pick改为edit,表示继续使用该条commit并且停止以便于amending。
    保存退出,那么当前状态处于一个类似阻塞的状态,然后让我们修正糟糕的提交。
    所以,修正完之后:

    $ git add .
    $ git commit --amend
    $ git rebase --continue

    值得注意的一点就是,如果当前分支所有的commit已经push到中央仓库,该操作会导致后续 git push 遭遇 [push reject],原因是中央仓库之后包含本地没有的commit,这个commit就是刚刚被替换掉的commit,这种情况需要用到:

    $ git push origin branch -f

    这种操作是明确本地commit就是想要的,然后强制覆盖中央仓库的commit,一般情况下(团队多人项目、分支),还是慎用。

  • 舍弃一次无比无比糟糕的提交

    舍弃某次糟糕提交之后的所有提交
    git reset --hard [目标commit]

    $ git reset --hard head^

    舍弃指定糟糕的提交
    git rebase -i [目标commit] ,然后使用command: drop, 保存退出。

    还可以,使用rebase --onto [基点commit] [起点commit] [终点commit] 来做:
    譬如当前master分支上有 [commit1、commit2、commit3、commit4]。
    现在我需要舍弃commit3这次糟糕的commit

    $ git rebase --onto commit2 commit3 master

    起点提交 commit3 在执行之后被舍弃,变为:
    [commit1、commit2、commit5]

  • 处理已经push到中央仓库的commit
    git revert [目标commit]

    $ git revert head^

    有意思的一点是,这个操作不会删除目标commit,而是会生成一个新的commit,这个commit和目标commit的内容是相反的,形成反转,达到撤销的效果。

  • reset 本质
    reset --hard [目标commit] 我们知道可以用来撤销某次糟糕的撤销,但是其本质不仅仅是如此。

    事实上,这个操作的本质是将当前HEAD以及branch移动到[目标commit]。
    而reset的 参数也有讲究,譬如我们用到的 <–hard> ,它在移动HEAD和branch的同时,还会舍弃掉当前[未提交]状态的所有改动。

    所以,它还有另外的参数 <–soft> , 表示保留原来状态为[changed to be commit]的改动,以及将移动HEAD之后带来的差异commit内容置为 [changes to be commit]

    如果reset不带参数,和<–soft> 类似,只是所有[changes to be commit]状态变为[changed not staged for commit]。

  • reset 和checkout的不同

    二者都是改变HEAD的位置,区别在于reset会带着branch一起移动,而checkout将使HEAD与当前branch脱离直接指向某个commit。

  • 临时存放工作目录的变动
    当工作目录有了一些改动,但是这些改动还不注意构成一次提交时,可以使用git stash -u命令

    $ git stash -u
    $ git checkout master

    -u 是 --include-untracked 的简写,意思是状态为[untracked files] 也会被临时存放

    当再次回来时,可以恢复临时存放的工作目录的变动

    $ git checkout new-feature
    $ git stash pop

    多个分支存在任务的时候,git stash的用法

    git stash save -u “feature1 temp message”
    git checkout feature2
    git stash save -u “featrue2 temp message”
    git checkout feature1
    git stash list
    git stash pop stash@{id}

  • 恢复刚删除的branch

    不小心手残删除了一个还有用的branch?

    $ git reflog

    该操作是查看仓库的HEAD引用移动记录,然后找到删除branch变动之前的commit,使用 checkout命令检出这个commit, 重新创建branch。

    $ git checkout
    $ git checkout -b branch-1

    值得注意的是,不再被引用的branch或者commit,在一段时间之后会被Git回收,所以这种操作一定要及时。

  • cherry-pick
    当Git工作目录包含IOS、Android、React-Native等大杂烩时,只需要合并指定commit,比如只合并Android相关的commits?

    $ git cherry-pick [Android Commit1] [Android Commit2] …

  • 使用git fetch和git rebase处理多人开发同一分支的问题
    当多人在同一分支开发时,如果在远程分支其他人先于自己push了一些提交,这时候自己的push会被拒绝而失败。
    所以,一般我们会git pull操作,然后git push,我们知道git pull是 git fetch和 git merge的组合操作,是先同步远程分支到本地,然后将远程分支和本地分支合并,这样最后会在本地产生一个额外的Commit,其message形如:

    “Merge branch ‘feature/a’ of origin/feature/a”
    

    这并不怎么优雅,至少在合并没有冲突的时候,这是一个空内容的Commit。
    所以,替换的操作是:

    $ git fetch
    $ git rebase origin/feature

    之后再push。

参考文档

by wxsmile

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值