git-02-基本操作

[TOC]

说明

本篇文章是本人回顾git知识点时从《progit》一书中摘抄出来的笔记,毕竟好记性不如烂笔头嘛,不然我也不会回顾了……
另请大神绕路,不喜勿喷……


本篇文章先走马观花般地看看git的使用,具体的每条命令的详解请看后续文章


本篇文章篇幅比较长,是本人回顾git知识点时从《progit》一书中摘抄出来的笔记,毕竟好记性不如烂笔头嘛,不然我也不会回顾了……
另请大神绕路,不喜勿喷……

1 获取git仓库

1.1 建立空仓库

$ git init <repo-name>

1.2 将已有目录纳入git仓库

$ cd some_dir
$ git init

1.3 clone现有本地仓库

$ git clone <location> [new-name]
$ git init repo-1
Initialized empty Git repository in G:/tmp/git-tmp/repo-1/.git/

# 克隆仓库repo-1 并重命名为repo-1-clone
# 也可以不指定别名 但此处若不指定别名会有两个相同名字的仓库而报错
$ git clone repo-1/ repo-1-clone
Cloning into 'repo-1-clone'...
warning: You appear to have cloned an empty repository.
done.

1.4 clone现有远程仓库

git clone <remote-url> [new-name]
# clone远程仓库不指定新仓库名
$ git clone https://github.com/java-template/jt-808-protocol.git
Cloning into 'jt-808-protocol'...
remote: Counting objects: 57, done.
remote: Compressing objects: 100% (47/47), done.
remote: Total 57 (delta 5), reused 50 (delta 2), pack-reused 0
Unpacking objects: 100% (57/57), done.

# clone远程仓库并重命名为jt-808-protocol-new
$ git clone https://github.com/java-template/jt-808-protocol.git jt-808-protocol-new
Cloning into 'jt-808-protocol-new'...
remote: Counting objects: 57, done.
remote: Compressing objects: 100% (47/47), done.
remote: Total 57 (delta 5), reused 50 (delta 2), pack-reused 0
Unpacking objects: 100% (57/57), done.

# 两个仓库如下
$ ls
jt-808-protocol/  jt-808-protocol-new/

2 记录变更

初次克隆某个仓库的时候,工作目录中的所有文件都属于已跟踪文件,也是未修改状态。
当你修改了文件的内容后,文件的特征码就变了,此时文件处于已修改状态。

来看看《progit》一书中对git文件状态变更的图解:

文件状态变更

该小节的命令都是在以下的repo-2中操作的:

$ git init git-repo-2
Initialized empty Git repository in G:/tmp/git-tmp/git-repo-2/.git/

$ cd git-repo-2/

2.1 git status

该命令可以用来查看文件的状态:已修改,未跟踪等。

新建的仓库,或者刚刚clone过来的仓库都是非常“干净的”。
此时使用status命令会显示工作区是clean的。

$ git status
On branch master

Initial commit

nothing to commit (create/copy files and use "git add" to track)

默认情况下,git status命令的输出非常多,可以加选项-s--short来简化输出。

# 添加个新的空白文件index.html
$ touch.exe index.html

#查看状态
$ git status
On branch master

Initial commit

Untracked files: # 未跟踪的文件列表如下
  (use "git add <file>..." to include in what will be committed)

        index.html

nothing added to commit but untracked files present (use "git add" to track)


$ git status -s
?? index.html

git status -s 简化输出后,最前面的两个问号表示未跟踪的文件。其他的前缀情况下文。

git status 前缀说明

  • ??: 新添加的未跟踪文件
  • A: 新添加到暂存区中的文件
  • M: 修改过的文件
    • 出现在右边的 M 表示该文件被修改了但是还没放入暂存区
    • 出现在靠左边的 M 表示该文件被修改了并放入了暂存区

2.2 git add

该命令将修改过的文件加入暂存区,待下次提交到历史记录。

$ git add index.html
$ git status 
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

    new file:   index.html

$ git status -s
A  index.html
$ 

git status -s 简化输出后,最前面的A表示新添加到暂存区中的文件。

# 修改文件index.html
$ echo "hello" >> index.html 

# A--在暂存区,M--修改过
$ git status -s
AM index.html
$ git add index.html
$ git status -s
A  index.html
$ 

2.3 git commit

该命令将暂存区中待提交的文件提交到历史记录中。

git commit
git commit -m "some notes"
$ git commit -m "first commit"
[master (root-commit) e500b7a] first commit
 2 files changed, 2 insertions(+)
 create mode 100644 index.html
 create mode 100644 main.html

当然,也可以跳过git add这一步,直接将修改的文件加入历史记录。使用选项-a即可。

git commit -a
git commit -a -m "some notes"

2.4 git rm

如果有个已被git管理(跟踪)的文件不想被管理了。
那么应该从暂存区中移除它,而后再次提交即可。

而命令git rm就是从暂存区移除文件的。

//从暂存区移除main.html
(master) $ git rm main.html
rm 'main.html'

// D表示已删除
(master) $ git status -s
D  main.html

//从暂存区移除后,提交到历史记录
(master) $ git commit -m "del main.html"
[master b05b2e9] del main.html
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 main.html

使用选项--cached可以从历史记录中删除文件。

2.5 .gitignore

在实际工作中,往往有些文件我们是不需要提交到历史记录的。

比如:eclipse等IDE产生的工程配置文件.project,.classpath等。

此时,.gitignore文件就派上用场了。在该文件中的内容都是git忽略的文件。
只需要在和.git目录同级创建一个名为.gitignore的文件即可。

在该文件中写入文件名、目录名等即可(支持通配符)。
以下是该文件中一些特殊的写法:

*.[oa]      # test.a test.o
!abc.o      # 该文件(abc.o)不被忽略
\!abc.f     # 此处转义,代表文件名为"!abc.f"的文件被忽略

xyz     # 文件xyz将被忽略
xyz/    # 录xyz将被忽略
**/xyz  # 所有目录下名为xyz的子目录将被忽略

2.6 git diff

就像《progit》一书中说的,你会经常想:哪些文件以及修改了,但是没有添加到暂存区?哪些文件暂存了,但是没有提交?

此处说的git diff可以用来干这事。它也能比较某个文件在不同版本之间的变更。

  • git diff : 工作区和暂存区之间的差异
  • git diff --cached : 暂存区和历史记录之间的差异
  • git diff --staged : 同上

2.7 git tag

该命令可以给某个特定的历史提交打上标记,以区分于其他普通的历史提交。

此处以git的项目仓库作为示例,看看tag的基本操作:

$ git clone https://github.com/git/git.git
Cloning into 'git'...
remote: Counting objects: 217337, done.
remote: Total 217337 (delta 0), reused 0 (delta 0), pack-reused 217337
Receiving objects: 100% (217337/217337), 78.90 MiB | 893.00 KiB/s, done.
Resolving deltas: 100% (159424/159424), done.

$ cd git

列出标签

# 列出所有tag
$ git tag
gitgui-0.10.0
gitgui-0.10.1
gitgui-0.10.2
gitgui-0.11.0
……………………
v2.9.0-rc2
v2.9.1
v2.9.2
v2.9.3


# 过滤
$ git tag -l 'v2.9.*'
v2.9.0
v2.9.0-rc0
v2.9.0-rc1
v2.9.0-rc2
v2.9.1
v2.9.2
v2.9.3

标签类型

  • 轻量标签(lightweight):一个特定提交的引用
  • 附注标签(annotated):存储在 Git 数据库中的一个完整对象
    • 打标签者的名字、电子邮件地址、日期时间
    • 还有一个标签信息
    • 并且可以使用 GNU Privacy Guard(GPG)签名与验证

为当前历史记录创建普通标签

# 创建普通标签
$ git tag 'my-tag-1'

# 列出标签
$ git tag -l 'my*'
my-tag-1

# 显示详细信息
$ git show my-tag-1
commit 80ba04ed9b07c34af9cc644f2183b3b80fd81744
Merge: 2076907 22af6fe
Author: Junio C Hamano <gitster@pobox.com>
Date:   Mon Feb 20 22:01:59 2017 -0800

    Merge branch 'svn-escape-backslash' of git://bogomips.org/git-svn

    * 'svn-escape-backslash' of git://bogomips.org/git-svn:
      git-svn: escape backslashes in refnames

为当前历史记录创建附注标签

# 创建附注标签
$ git tag -a 'my-tag-2' -m 'my tag 2'

$ git tag -l 'my-tag*'
my-tag-1
my-tag-2

# 显示内容
$ git show my-tag-2
tag my-tag-2
Tagger: hylexus <hylexus@163.com>
Date:   Thu Feb 23 16:41:05 2017 +0800

my tag 2 # 此处的信息为创建时指定的-m选项的内容

commit 80ba04ed9b07c34af9cc644f2183b3b80fd81744
Merge: 2076907 22af6fe
Author: Junio C Hamano <gitster@pobox.com>
Date:   Mon Feb 20 22:01:59 2017 -0800

    Merge branch 'svn-escape-backslash' of git://bogomips.org/git-svn

    * 'svn-escape-backslash' of git://bogomips.org/git-svn:
      git-svn: escape backslashes in refnames

为指定的历史提交创建附注标签

#为指定的历史提交创建附注标签
# 显示最近两次的提交
$ git log --oneline -2
80ba04e Merge branch 'svn-escape-backslash' of git://bogomips.org/git-svn
2076907 Git 2.12-rc2

# 为倒数第二次历史提交添加附注标签
$ git tag -a 'tag-2-1' 2076907 -m 'tag test'

# 查看
$ git show tag-2-1
tag tag-2-1
Tagger: hylexus <hylexus@163.com>
Date:   Thu Feb 23 16:59:38 2017 +0800

tag test

commit 20769079d22a9f8010232bdf6131918c33a1bf69
Author: Junio C Hamano <gitster@pobox.com>
Date:   Fri Feb 17 14:00:19 2017 -0800

    Git 2.12-rc2

    Signed-off-by: Junio C Hamano <gitster@pobox.com>

3 查看提交历史

所有的历史提交记录都在.git目录中,可以使用git log来查看历史。

默认情况下,git log 会按提交时间列出所有的更新,最近的更新排在最上面。
列出每次提交的SHA-1校验和、作者的名字和电子邮件地址、提交时间以及提交说明。

此处就以《progit》一书中的仓库来做示例:

$ git clone https://github.com/schacon/simplegit-progit my-pro
$ cd my-pro
$ git log
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gmail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the verison number

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gmail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    removed unnecessary test code

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gmail.com>
Date:   Sat Mar 15 10:31:28 2008 -0700

    first commit

git log 常用选项

  • -p : 每次提交的内容差异
  • -n : n是一个正整数,表示只显示最近n次的提交
  • --stat : 显示每次提交的概述性信息
  • --shortstat : 只显示--stat中的最后的统计信息
  • --name-only : 仅在提交信息后显示已修改的文件清单
  • --name-status : 显示新增、修改、删除的文件清单
  • --abbrev-commit : 仅显示SHA-1特征码的前几个字符,而非所有的40个字符
  • --relative-date : 使用较短的相对时间显示(比如,“2 weeks ago”)
  • --pretty : 使用其他格式显示历史提交信息
    • oneline
    • short
    • full
    • fuller
    • format
  • --graph 显示 ASCII 图形表示的分支合并历史
# 显示最近两次提交的概述性信息
$ git log --stat -2
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gmail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the verison number

 Rakefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gmail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    removed unnecessary test code

 lib/simplegit.rb | 5 -----
 1 file changed, 5 deletions(-)


# 最近两次提交,统计信息
$ git log --shortstat -2
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gmail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the verison number

 1 file changed, 1 insertion(+), 1 deletion(-)

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gmail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    removed unnecessary test code

 1 file changed, 5 deletions(-)



$ git log --graph --all --decorate --oneline
* ca82a6d (HEAD -> master, origin/master, origin/HEAD) changed the verison number
* 085bb3b removed unnecessary test code
* a11bef0 first commit


$ git log --pretty=format:"%h - %an, %ar : %s"
ca82a6d - Scott Chacon, 9 years ago : changed the verison number
085bb3b - Scott Chacon, 9 years ago : removed unnecessary test code
a11bef0 - Scott Chacon, 9 years ago : first commit

来自《progit》一书中的截图:

pretty
git log limit

4 撤销操作

4.1 amend

git commit --amend

该命令会将暂存区中的文件提交。
如果自上次提交以来你还未做任何修改(例如,在上次提交后马上执行了此命令),那么快照会保持不变,而你所修改的只是提交信息。

可以达到覆盖提交注释的目的。

4.2 git reset

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   Main.java
        modified:   index.html

正如git给你提示的一样:use "git reset HEAD <file>..." to unstage。
可以使用 git reset HEAD <file-name-list>来将文件取消暂存。

$ git reset HEAD Main.java index.html
Unstaged changes after reset:
M       Main.java
M       index.html

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   Main.java
        modified:   index.html

no changes added to commit (use "git add" and/or "git commit -a")

4.3 checkout -- file

git checkout -- file

该命令可以将文件还原成上次提交时的样子。

reset 和 git checkout -- file的区别

简言之,git checkout -- file修改工作区,而git reset修改的是暂存区。

5 别名

linuxshell命令一样,你可以给git命令起简短的别名以方便使用。

linux bash命令别名

$ alias ll='ls -a -l'

此时ll就和ls -a -l一样了。

git 别名示例

$ git config --global alias.lol 'log --decorate --graph --all --oneline'
$ git config --global alias.ci commit

现在,就可以使用git ci来代替git commit了。

其实,和linux系统一样,git所有的配置都是在配置文件里的:

# global级别的配置文件内容如下
$ cat ~/.gitconfig
[user]
        name = hylexus
        email = hylexus@163.com
[alias]
        lol = log --decorate --graph --all --oneline
        ci = commit
[credential]
        helper = manager

参考资料

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

推荐阅读更多精彩内容

  • 1.git的安装 1.1 在Windows上安装Git msysgit是Windows版的Git,从https:/...
    落魂灬阅读 12,648评论 4 54
  • 来源:Git由浅入深之操作与指令作者:惊鸿三世(转载已获得原作者许可,如需转载请与原作者联系) 本篇正式开始介绍G...
    极乐君阅读 1,625评论 9 67
  • 文/兰馨瑶 01 “金国今天还没下楼来?”老余一进门,就问老婆李秋凤。 李秋凤摇摇头,满面愁容:“饭都是我端上去的...
    兰馨瑶阅读 1,534评论 0 3
  • 01/“我们每个人都是孤岛,但不是所有人都会相逢。” 老朋友见面,敷一落座,就“恭维”起我来。 “好久不见,你是更...
    凭栏望云阅读 276评论 0 3
  • 依我们这的风俗,冬至那天是要喝鸡汤的,头天晚上,我妈就趁着鸡上宿的时候,捉住了那只喂了半年的乌鸡。可我妈是出了名的...
    漆小吾阅读 483评论 4 2