Git和Github速查表

一. 版本控制术语

  • 版本控制系统(VCS):管理不同版本源代码的系统
  • 提交(commit):将源代码的变动提交到VCS中进行“存档”
  • 仓库(repository):由多次提交所组成的代码库
  • 工作目录(working directory):存在于本地文件系统的源代码目录
  • 签出(checkout):从仓库中“读档”某次提交
  • 暂存区:用来存放下一次将被提交到仓库的变更
  • SHA:每次提交的唯一ID
  • 分支:从开发主线分离出来的开发支线

二. 创建Git仓库

1. 创建新的仓库

git init会创建.git文件夹,包含以下内容:

  • config文件:与项目有关的配置文件
  • description文件:GitWeb程序相关,可忽略
  • hooks文件夹:存放客户端或服务端脚本,作为钩子程序在Git的不同生命周期事件中被调用
  • info文件夹:包含一个全局型排除文件,用来追踪不希望被记录在.gitignore文件中的忽略模式
  • objects文件夹:存放所有的提交
  • refs文件夹:存放指向数据(分支和标签)的提交对象的指针(分支和标签)
  • HEAD文件:指示目前被检出的分支
  • index文件:保存暂存区信息

进阶阅读

2. 克隆已存在的仓库

git clone <path-to-repo-to-clone>命令从指定的URL克隆仓库,可以在URL后追加名字重命名仓库。

进阶阅读

3. 查看仓库状态

git status查看仓库的当前状态,特别是有没有还未提交的修改。

进阶阅读

三. 浏览仓库提交记录

git log命令浏览仓库的提交历史记录。默认会显示SHA,作者,日期和提交信息。

git log --oneline显示短SHA和提交信息。

git log --stat显示每次提交发生改变的文件,以及被添加/删除的代码行数。

git log -p/--patch显示文件中发生的详细修改信息。

git log -p --stat将上述两者结合显示统计信息和详细修改信息。

git log -w忽略空白行。

git log --decorate显示隐藏的细节信息,比如打好的标签和分支信息。

git log --oneline --decorate --graph --all命令显示所有分支的图形化信息。

进阶阅读

git log/show 短SHA查看某次提交。git show命令默认显示提交,作者,日期,提交信息和补丁信息。同样适用以下参数:

  • --stat - 显示有多少文件被修改,以及添加/删除的代码行数
  • -p or --patch - 默认显示补丁信息,但如果使用了 --stat 则补丁信息不会显示,需要再加上这个参数
  • -w - 忽略空白行

四. 提交代码

1. 代码提交到暂存区

git add <file>将文件提交到暂存区,git add .`将所有变更都提交到暂存区。

git rm --cached <file>将提交到暂存区的文件删除。

2. 将暂存区代码提交到本地仓库

git config --global core.editor <your-editor>配置编写commit message的文本编辑器。

git commit提交代码,会弹出配置好的文本编辑器,用于输入本次提交所需提供的commit message。在文本编辑器中写好之后保存退出,代码就提交到本地仓库中。

或者使用git commit -m 'xxx'来直接附加简单的提交信息。

进阶阅读

3. 查看没有提交的改变

git diff命令可以用来查看还没有提交到本地仓库的改变,它显示:

  1. 被修改的文件
  2. 发生添加或删除的代码行位置
  3. 发生了什么样的改变

进阶阅读

4. 忽略不想提交的文件

对于不想提交的文件,可以使用.gitignore文件进行忽略。.gitignore文件可以使用通配符:

  • blank lines can be used for spacing
  • # - 注释
  • * - 匹配0个或多个字符
  • ? - 匹配1个字符
  • [abc] - 匹配 a, b, 或 c
  • ** - 匹配嵌套目录 - 比如a/**/z 匹配
    • a/z
    • a/b/z
    • a/b/c/z

进阶阅读

五. 标签,分支和代码合并

1. 给代码打标签

git tag -a v1.0给最近一次提交的代码打上“v1.0”标签。同样会弹出文本编辑器用于输入必要信息。

git tag命令列出所有的标签。

git tag -d v1.0删除标签。

git tag -a v1.0 a87984给某次提交打标签

进阶阅读

2. 分支管理

git branch命令查看所有的分支,活跃分支以*标记。

git branch sidebar创建一个叫sidebar的分支。

git branch alt-sidebar-loc 42a69f创建一个叫alt-sidebar-loc的分支,该分支基于SHA为42a69f的提交创建。

git checkout -b footer master从master分支创建footer分支。

git branch -d sidebar删除名为sidebar的分支。

git checkout sidebar切换到sidebar分支。

进阶阅读

3. 代码合并

git merge <name-of-branch-to-merge-in>将其他分支代码合并到当前分支。

分支合并的工作原理:

  • 检查要被合并的分支
  • 回溯分支历史找到两个分支共同的祖先
  • 合并两个分支上发生改变的代码
  • 创建一次提交来记录合并操作

如果b分支从a分支创建出来有了几次提交,而a分支在这个过程中没有任何提交,那么此时将b分支合并到a分支的操作被称为“快进合并”(fast-forward merge)。相当于分支指针往前移动。反之,如果a分支在这个过程中有了自己的提交,那么两个分支的合并操作就是常规合并。

进阶阅读

4. 解决冲突

如果在多个分支中修改了相同的代码行,就会导致合并冲突,进而造成合并失败。Git会尽量合并能合并的代码,无法合并的地方会用>>><<<标记,需要手动修复。

合并冲突标记解释:

  • <<<<<<< HEAD 从这行往下直到下一个标记之前所有的内容显示当前分支冲突区域是什么样的。
  • ||||||| merged common ancestors 从这行往下直到下一个标记之前所有的内容显示修改之前原始的代码行。
  • ======= 表示原始代码行的终点,从这行往下直到下一个标记之前的内容显示被合并的分支冲突域是什么样的。
  • >>>>>>> <分支名> 被合并分支冲突域的结束标记。

手动修复代码后保存,然后进行常规的代码提交工作即可。

进阶阅读

五. 撤销操作

1. 修改上一次提交

如果当前工作目录是干净的,git commit --amend命令会弹出文本编辑器,我们可以修改上一次的提交信息,然后重新保存覆盖。如果我们发现有文件漏改了,可以修改文件,保存文件,将文件提交到暂存区,然后使用该命令将漏改的文件更新到上一次的提交记录中。

2. 回滚提交

git revert <SHA-of-commit-to-revert>回滚某次提交的代码,撤销那次提交所做的所有修改,并创建一个新的提交来记录改变。

进阶阅读

3. 重置提交

不同于回滚,重置提交会将提交从历史记录中彻底抹掉。被彻底抹掉的信息会被Git保留30天,可以使用git reflog访问到这些信息。

进阶阅读

在对提交进行重置时,常常需要指定从某次提交开始之前的某个相对位置:

  • ^ – 表示父提交
  • ~ – 表示第一个父提交

比如当前(HEAD)提交的父提交可以表示为:

  • HEAD^
  • HEAD~
  • HEAD~1

当前提交的祖父提交为:

  • HEAD^^
  • HEAD~2

曾祖父提交:

  • HEAD^^^
  • HEAD~3

^~的区别在于,对于因为代码合并而产生的提交会有两个父提交,^表示第1个父提交,即合并代码时所在的分支;^2表示第2个父提交,即被合并的代码分支。举例:

* 9ec05ca (HEAD -> master) Revert "Set page heading to "Quests & Crusades""
* db7e87a Set page heading to "Quests & Crusades"
*   796ddb0 Merge branch 'heading-update'
|\  
| * 4c9749e (heading-update) Set page heading to "Crusade"
* | 0c5975a Set page heading to "Quest"
|/  
*   1a56a81 Merge branch 'sidebar'
|\  
| * f69811c (sidebar) Update sidebar with favorite movie
| * e6c65a6 Add new sidebar content
* | e014d91 (footer) Add links to social media
* | 209752a Improve site heading for SEO
* | 3772ab1 Set background color for page
|/  
* 5bfe5e7 Add starting HTML structure
* 6fa5f34 Add .gitignore file
* a879849 Add header to blog
* 94de470 Initial commit
  • HEAD^ 即SHA为 db7e87a的提交
  • HEAD~1 也是SHA为 db7e87a 的提交
  • HEAD^^ 即SHA为 796ddb0 的提交
  • HEAD~2 也是SHA为 796ddb0 的提交
  • HEAD^^^ 即SHA为 0c5975a 的提交
  • HEAD~3 也是SHA为 0c5975a 的提交
  • HEAD^^^2 即SHA为 4c9749e 的提交 (祖父提交 (HEAD^^) 的第2个父提交 (^2))

git reset <reference-to-commit>命令用于重置(消除)提交。作用:

  • 移动HEAD和当前分支指针到某次提交
  • --hard清除提交
  • --soft将提交的改变移回暂存区
  • --mixed将提交的改变移回工作目录
* 9ec05ca (HEAD -> master) Revert "Set page heading to "Quests & Crusades""
* db7e87a Set page heading to "Quests & Crusades"
* 796ddb0 Merge branch 'heading-update'

git reset --mixed HEAD^命令会将9ec05ca中的提交移回工作目录;git reset --soft HEAD^命令会将9ec05ca中的提交移回暂存区;git reset --hard HEAD^会将9ec05ca中的提交彻底清除。

进阶阅读

六. 与远程仓库协作

Git是一个分布式的版本控制系统,在多人协作开发的模式下,每一个开发者都有项目代码的一份拷贝。远程仓库可以通过URL或者文件系统路径的方式访问,其中URL是最常见的方式。可以为每个本地仓库配置与多个远程仓库的连接。

1. 添加远程仓库

通过git remote命令完成与远程仓库的各种交互。该命令用于显示该仓库与远程仓库的联系。命令显示每个与之有关的远程仓库的短名,比如仓库是从远程clone下来的,那么默认会显示originorigin默认代表主远程仓库,短名可以被重命名。

git remote -v显示远程仓库的短名和与之相对应的完整路径:

origin  https://github.com/leesper/become-cloud-developer.git (fetch)
origin  https://github.com/leesper/become-cloud-developer.git (push)

在Github上创建好远程仓库之后,可以使用如下命令将其与本地仓库关联起来:

git remote add origin https://github.com/xxx/yyy.git

进阶阅读

2. 推送提交到远程仓库

git push <remote-shortname> <branch>命令将分支代码推送到远程仓库,例如git push origin master,此时如果使用git log命令查看提交记录,就会发现多了一个叫origin/master的跟踪分支,即远程仓库origin具有一个分支master,可以使用这个信息来追踪远程仓库的情况。

3. 从远程仓库更新

git pull origin master从远程仓库origin中拉取master分支的代码。

4. Pull和Fetch

如果远程仓库有本地仓库没有的提交,同时本地仓库也有远程仓库没有的提交,这时就需要使用git fetch命令来从远程拉取代码。git fetch从远程拉取代码,但不会自动合并到本地。

git fetch origin master将从远程仓库拉取代码到本地仓库,本地的追踪分支移动并指向最近的一次提交记录,但本地分支不会发生改变。相当于fetch只做了pull的一半工作。将代码拉取到本地后,可以使用git merge origin/master来手动合并代码。然后推送代码到远程仓库。

5. 为别人的项目贡献代码

当我们需要给别人的项目贡献代码时,我们首先需要在Github上点击fork按钮将别人的代码分叉到自己的账号下,形成一个独立的拷贝,然后在这个拷贝上进行相关的代码维护,并最终将自己的贡献合并到别人的仓库中(通过Pull Request)。

当开发者作为小组成员参与到一个项目中时,最重要的事情是首先了解项目当前的进度,特别是各开发分支的工作进度。git log作为强大的命令可以满足我们的要求,下面总结几个相关的命令。

git shortlog命令按照提交者分组显示相关提交信息,按照提交者名字字母排序显示。

git shortlog -s -n显示每个提交者的提交次数,降幂排序。

git log --author=Surma查看所有Surma的提交。

git show 5966b66查看SHA为5966b66的提交。

git log --grep=bug筛选带bug关键字的提交记录。

可以通过查看CONTRIBUTING.md文件来确定要开展的工作。某些项目会通过该文件告诉开发者维护或者贡献项目所必须遵循的相关信息。如果提交的改动比较大,那么可能需要在Github Issues中先征得项目维护者的同意,也可以通过该列表了解其他开发者是否遇到过类似问题。与相关开发人员进行充分的沟通之后再开展工作,避免自己的贡献变成无用功。

开发工作完成后,可以在自己fork的副本中创建PR,向源项目申请提交贡献,此时源项目的作者会审阅你的代码,并评估是否合并到源仓库中,或者向你提出修改意见。要想与源项目保持同步,首先可以STAR,STAR越多的项目流行度越高;其次可以WATCH该项目,这样当项目有任何变更我们都能在Github主页上及时看到。另外我们还可以为副本仓库添加对上游源项目的跟踪来保持与源项目的同步。

git remote add upstream https://github.com/xxx/yyy.git命令将源项目指定为短名upstream

git fetch upstream master可以从源项目的远程仓库中拉取代码到本地。也可以通过git pull upstream master拉取并合并代码到本地。

git merge upstream/master然后git push origin master可以将源项目代码合并到本地,然后推送到自己的代码副本。

6. 使用rebase命令合并提交

git rebase -i HEAD~3命令以最近一次提交的曾祖父提交为base,将HEAD~2HEAD~1,和 HEAD合并为一次提交。合并后将代码同步到远程仓库时,需要git push -f命令强制同步。rebase命令可以干很多事情:

  • ppick – 保持原有提交不变
  • rreword – 提交内容不变,但修改commit message
  • eedit– 提交内容不变但保持提交前的状态,然后我们可以:
  • 添加新内容或文件
  • 删除内容或文件
  • 修改本来是要提交的内容
  • ssquash – 将这次代码提交的改变合并到前一次提交中(列表中的上一个)
  • ffixup – 将这次代码提交的改变合并到前一次提交中,删除commit message
  • xexec – 运行shell命令
  • ddrop – 删除提交

注意:如果代码已经推送到远程仓库,最好不要执行rebase命令,因为这会清除某些提交记录,导致其他开发者的本地仓库与远程仓库不同步从而产生严重问题。

进阶阅读

七. 读别人的代码,然后自己写代码

这里列举的一些资源对新人快速上手并贡献代码有帮助:

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容

  • 一、基本概念: 注:对于git的分布式概念及其优点,不重复说明,自己百度或谷歌。本文中涉及到指令前面有$的,在cm...
    大厂offer阅读 1,335评论 0 3
  • 简介 Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。 Git 与常用的版本控制工具 ...
    闽越布衣阅读 2,681评论 0 18
  • Git 是目前最流行的分布式版本控制系统之一。 版本控制指的是,记录每次版本变更的内容和时间等细节,保留各版本之间...
    神齐阅读 1,322评论 0 7
  • Add & Commit git init 初始化一个 Git 仓库(repository),即把当前所在目录变成...
    冬絮阅读 4,674评论 0 8
  • 听说撒就散这首歌的时候,还没关注这部电影,第一次听就喜欢上这首歌。女生可能天生都是多愁善感的,像这种很有画面感的歌...
    梵萱阅读 218评论 0 0