Windyland 内核崩坏

一切皆源Git而起

项目管理场景

  • 源文件追踪历史
  • 保存旧版本
  • 版本发布

常见的项目管理系统

  • CVS
  • SVN
  • GIT
  • Mercurial

GIT 的常见命令

  • git init

初始化当前目录为git管理,(如果当前有.git 目录,通常是已经被git管理的情况,会提示报错),初始化会在当前目录下生成.git 目录,保存有版本管理的一切信息。

此操作会初始化默认分支(下面称为branch)为master 分支

  • git add [file] [file2] …

添加指定文件到git的stage 区域, 和SVN等早期的项目管理不同,这个区域的不会涉及到更新到新版本,只是暂时保存你的修改。

stage 态的文件 可以通过 git reset [file] 的方式释放会stage 区域的内容。

  • git commit [-m message]

将stage 态的文件全部 提交(本地)到新版本(下面简称“提交commit”), 默认会弹出一个文本编辑器提供填写修改日志。 也可以直接通过-m message 跳过文本编辑器直接写入你的修改日志。

只有Stage态的文件才可以提交commit

  • git clone [repo url]

远程抓去一个git 源(下面称为git repository, 或者repo), 保存在你当前目录下。

此操作会初始化默认分支(下面称为branch)为master 分支, 远程(下面称为remote)为 origin

GIT 的工作状态

  • untracked 无关区域,使用git status 命令会显示对应文件为一个 ?(红色)
  • uncommited/modified 未提交态,使用git status 命令会显示对应文件为一个 M(红色)
  • staged git检测出此文件已修改,而且此修改已经被保存进stage态了, git status 命令会显示为一个M(绿色) 或者A/D
  • commited git status 没有相关的提示

GIT 的本地和远程交互

git 通常会在本地保存有整个完整的历史,这和早期的CVS、SVN不同。 所以向远程服务器抓去更新或者推送更新,不如说是历史记录的更新。

  • git pull

最常用的抓去操作,将远程分支的信息抓去合并到本地,早期时候是非常常见的。 但是经过大量的git使用经历,很多项目管理者并不推荐这个命令。

有兴趣可以抓个linux 内核的 分支信息图像看看滥用这个命令的效果图 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git

  • git push

推送操作,将本地特定的分支信息推送到服务器的对应分支上。

  • git fetch [remote]

remote 没有指定时候 会指向默认的remote。 此操作会抓去remote 上所有的分支信息。

  • git merge [branch]

通常是3-way merge, 此操作不会涉及到远程网络,因为它的工作原理是将branch 的分支历史 通过3-way merge 算法(涉及到当前分支、branch 分支、和两个分支的共同祖先),将branch上的分支信息合并到 当前分支上。

由于操作完成后的历史是以当前历史为起点的,所以项目维护者通常会非常喜欢这个。

  • git rebase [branch]

工作原理是将当前分支改写为branch分支的信息,然后再将通过计算的原当前分支的分支历史, 逐个commit合并到到现有的分支上。

此操作通常会改写当前分支的历史,所以比较危险。

  • 重看git pull

git pull 其实是两步操作的合成 git pull = git fetch + git merge

后面的操作可以通过 git config –global push.rebase true 改为使用rebase

即 git pull = git fetch + git rebase

git 源代码本身就有很多脚本(shell 或者perl),所以直接何用两步作为新的命令不足为奇

GIT 的项目管理常用操作

  • 之前说的作为分支管理者,常用的是 git merge

    好处是不会改写大家公用的历史

  • 作为功能开发者或者补丁提交者,常用的是 git rebase

    好处是将自己的私人历史控制在一起,减少合并时需要处理的冲突(通常只要按最新的历史处理就可以了), 可以方便的供分支管理者合并(merge)

  • 当然作为分支维护者,通常会收到各种patch 文件

通过 git am [patch file] 来吸收进到你的当前branch

如果这个补丁已经在你的repo 的某分支 或者repo的信息里了

通过 git cherry-pick [commit-id] 来吸收进你的当前branch中

commit-id 是指每个commit 唯一的sha1 值,一共是40位

  • 作为补丁开发者,通常会产生各种奇怪的patch文件

git 下产生两个commit的差集patch的快捷方式是 :

git format-patch [commit-1-id]..[commit-2-id]

  • 什么rebase, merge, am, cherry-pick 未完成时候想取消?

git [operator] –abort 回滚operator操作

GIT 的rev 行为

被认为REV的git 标签是 HEAD, branch(其实就是branch的HEAD), tag, commit-id

通过 git rev-parse [rev] 可以查询对应rev的 commit-id 哦

其他黑魔法

  • git branch -a 所有分支
  • git tag 所有tag
  • git remote -a 所有远程
  • git branch 当前分支
  • git diff 当前git信息差集(untracked, uncommited态与staged态对比)
  • git diff --staged 当前git信息差集(staged态与commited态对比)
  • git diff --stat 当前git信息差集的数据
  • git log 详细的日志
  • git log --graph --oneline 一个commit一行方式显示日志
  • git checkout - 切换 到上次的分支(类似 cd -)

Further Read (English)

Further Read (Extra)