Git教程

前言

Git是一款免费、开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。Git的读音为/gɪt/。
可以有效、高速的处理从很小到非常大的项目版本管理。Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

本教程部分的内容主要选自廖雪峰Git教程,很容易上手。仅供初学者学习,高手请绕路。


配置用户姓名以及Email

1.用户名和邮箱地址的作用:

  • 用户名和邮箱地址是本地git客户端的一个变量,不随git库而改变。
  • 每次commit都会用用户名和邮箱纪录。
  • github的contributions统计就是按邮箱来统计的。

2.查看用户名和邮箱地址:

$ git config user.name

$ git config user.email

3.修改用户名和邮箱地址:

$ git config --global user.name "username"

$ git config --global user.email "email"

创建版本库

1.mkdir xxx(创建一个本地xxx版本库);
2.pwd (显示当前目录) ;
3.git init(初始化这个目录变成Git可以管理的仓库);
4.ls -ah (查看隐藏的.git文件)。
仓库建好了,是一个空的仓库(empty Git repository),可以发现当前目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。

.git目录
Administrator@WIN-3CLRCDSGQIC MINGW32 /e/git
$ mkdir testgit

Administrator@WIN-3CLRCDSGQIC MINGW32 /e/git
$ cd testgit

Administrator@WIN-3CLRCDSGQIC MINGW32 /e/git/testgit
$ pwd
/e/git/testgit

Administrator@WIN-3CLRCDSGQIC MINGW32 /e/git/testgit
$ git init
Initialized empty Git repository in E:/git/testgit/.git/

Administrator@WIN-3CLRCDSGQIC MINGW32 /e/git/testgit (master)
$ ls -ah
./  ../  .git/

提交文件

1.添加文件至仓库的暂存区

  • git add <filename> (命令git add把文件添加到仓库);
Administrator@WIN-3CLRCDSGQIC MINGW32 /e/git/testgit (master)
$ git add readme.txt

2.提交暂存区的数据内容

  • git commit -m "提交的内容描述" (命令git commit把文件提交到仓库);
Administrator@WIN-3CLRCDSGQIC MINGW32 /e/git/testgit (master)
$ git commit -m "wrote a readme file"
[master (root-commit) d11a667] wrote a readme file
 1 file changed, 2 insertions(+)
 create mode 100644 readme.txt

-m后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。

3.多次add不同的文件,commit一次提交很多文件

$ git add file1.txt
$ git add file2.txt file3.txt
$ git commit -m "add 3 files."

查看当前仓库的状态以及修改内容

1.git status 查看仓库当前的状态

  • $ git status

2.git diff 查看具体修改了什么内容

  • $ git diff
Administrator@WIN-3CLRCDSGQIC MINGW32 /e/git/testgit (master)
$ 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:   readme.txt

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

Administrator@WIN-3CLRCDSGQIC MINGW32 /e/git/testgit (master)
$ git diff
diff --git a/readme.txt b/readme.txt
index d8036c1..013b5bc 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,2 +1,2 @@
-Git is a version control system.
+Git is a distributed version control system.
 Git is free software.
\ No newline at end of file

Administrator@WIN-3CLRCDSGQIC MINGW32 /e/git/testgit (master)
$ git add readme.txt

Administrator@WIN-3CLRCDSGQIC MINGW32 /e/git/testgit (master)
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   readme.txt


Administrator@WIN-3CLRCDSGQIC MINGW32 /e/git/testgit (master)
$ git commit -m "add distributed"
[master be220b4] add distributed
 1 file changed, 1 insertion(+), 1 deletion(-)

Administrator@WIN-3CLRCDSGQIC MINGW32 /e/git/testgit (master)
$ git status
On branch master
nothing to commit, working tree clean


查看历史记录

1.git log 查看提交历史
2.git log --pretty=oneline 查看提交历史并过滤
3.git reflog 查看命令历史

Administrator@WIN-3CLRCDSGQIC MINGW32 /e/git/learngit (master)
$ git log
commit 4683cef3c82bac221df5bec4eff97f9367ce5574
Author: Destiny <iamxufeng@users.noreply.github.com>
Date:   Wed Mar 15 15:58:21 2017 +0800

    Update hello.txt

commit d591d097ff31f7f7af4018c9ee53c30848d2da7d
Merge: 94616bc cd2924b
Author: Destiny <iamxufeng@users.noreply.github.com>
Date:   Wed Mar 15 15:44:06 2017 +0800

    Merge pull request #1 from iamxufeng/dev

    update readme.txt

Administrator@WIN-3CLRCDSGQIC MINGW32 /e/git/learngit (master)
$ git log --pretty=oneline
4683cef3c82bac221df5bec4eff97f9367ce5574 Update hello.txt
d591d097ff31f7f7af4018c9ee53c30848d2da7d Merge pull request #1 from iamxufeng/dev
cd2924b8097397309a11c15756eff39a4aca7c8a update readme.txt
94616bc9c948a2231380481feea59130a0cc689b add hello
93feb184a2a11777b82dc54e76344938740eba0c add gitignore

Administrator@WIN-3CLRCDSGQIC MINGW32 /e/git/learngit (master)
$ git reflog
4683cef HEAD@{0}: reset: moving to 4683cef
d591d09 HEAD@{1}: reset: moving to HEAD^
4683cef HEAD@{2}: pull: Fast-forward
d591d09 HEAD@{3}: pull: Fast-forward
cd2924b HEAD@{4}: checkout: moving from d591d097ff31f7f7af4018c9ee53c30848d2da7d to master
d591d09 HEAD@{5}: checkout: moving from dev to origin
cd2924b HEAD@{6}: checkout: moving from master to dev
cd2924b HEAD@{7}: merge dev: Fast-forward
94616bc HEAD@{8}: checkout: moving from dev to master
cd2924b HEAD@{9}: commit: update readme.txt
94616bc HEAD@{10}: checkout: moving from master to dev
94616bc HEAD@{11}: commit: add hello
93feb18 HEAD@{12}: clone: from git@github.com:iamxufeng/learngit.git


回退到上一个版本

HEAD表示当前版本,也就是最新的提交3628164...882e1e0(注意我的提交ID和你的肯定不一样);上一个版本就是HEAD,上上一个版本就是HEAD,当然往上100个版本写100个比较容易数不过来,所以写成HEAD~100。
1.回到当前版本
$ git reset --hard HEAD
2.回到当前版本的上一个版本
$ git reset --hard HEAD^
3.回到指定的提交ID的版本
$ git reset --hard <commitID>

Administrator@WIN-3CLRCDSGQIC MINGW32 /e/git/learngit (master)
$ git reset --hard HEAD^
HEAD is now at d591d09 Merge pull request #1 from iamxufeng/dev

查看当前文件与版本库中文件的差别

1.git diff HEAD -- <filename> (查看工作区和版本库里面最新版本的区别)
git diff HEAD -- readme.txt
2.工作区修改还原(即修改了本地的文件还没有使用git add 提交到暂存区)
git checkout -- <filename> 可以丢弃工作区的修改
3.从工作区提交到了暂存区(即修改了本地的文件并且使用git add 提交到暂存区)
git reset HEAD <filename> 可以把暂存区的修改撤销掉(unstage),重新放回工作区
git checkout -- <filename> 可以丢弃工作区的修改
4.从暂存区提交到了版本库并且没有推送到远程库(即修改了本地的文件并且使用git add 提交到暂存区,又git commit到版本库)
只能通过版本回退的方式撤销修改:

  • 回到当前版本
    $ git reset --hard HEAD
  • 回到当前版本的上一个版本
    $ git reset --hard HEAD^
  • 回到指定的提交ID的版本
    $ git reset --hard <commitID>

删除文件

1.一般情况下,你通常直接在文件管理器中把没用的文件删了,或者用rm命令删了:
$ rm <filename>
2.要从版本库中删除该文件,那就用命令git rm删掉,并且git commit
$ git rm <filename> $ git commit -m "descrition"

例如:

$ git rm test.txt
$ git commit -m "remove test.txt"

3.删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本:
$ git checkout -- <filename>

例如:

$ git checkout -- test.txt

添加远程仓库

  • 第1步:创建SSH Key。
    $ ssh-keygen -t rsa -C "youremail@example.com"
    把邮件地址换成你自己的邮件地址,然后一路回车,使用默认值即可,由于这个Key也不是用于军事目的,所以也无需设置密码。
    一切顺利的话,可以在用户目录下的.ssh目录中,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。

  • 第2步:登陆GitHub,打开“Account settings”,“SSH Keys”页面,然后,点“Add SSH Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容。

1.从远程仓库克隆工程至本地
$ git clone git@github.com:<address>/<project name>.git

例如:

$ git clone git@github.com:iamxufeng/learngit.git

2.把一个已有的本地仓库与远程仓库关联
$ git remote add <远程仓库名 一般写 origin>git@github.com:<address>/<project name>.git

例如:

$ git remote add origin git@github.com:iamxufeng/learngit.git

3.第一次推送master分支的所有内容,把本地库的所有内容推送到远程库上

$git push -u origin master 

之后推送最新的修改只需要

$ git push origin master

分支

1.创建分支branch name,然后切换到分支:
$ git checkout -b <branch name>
例如,创建dev分支,然后切换到dev分支::

$ git checkout -b dev

相当于以下两条命令:

$ git branch dev
$ git checkout dev

2.查看当前分支
$ git branch

3.分支的切换
$ git checkout <branch name>
dev分支的工作完成,我们就可以切换回master分支:
$ git checkout master

4.将分支内容与主干分支master合并

  • 使用Fast forward合并分支(不建议使用这种方式)
    $ git merge <branch name>
    必须使用$ git checkout master切换至master分支,然后在使用$ git merge dev合并。
  • 禁用Fast forward合并分支(推荐使用这种方式)
    $ git merge --no-ff -m "descrition" <branch name>
    请注意--no-ff参数,表示禁用Fast forward:
$ git merge --no-ff -m "merge with no-ff" dev

合并分支时,加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。
当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。用git log --graph命令可以看到分支合并图。

5.删除分支

  • 删除已经合并过的分支
    $ git branch -d <branch name>
    例如,删除dev分支:
$ git branch -d dev
  • 删除没有合并过的分支
    $ git branch -D <branch name>
    例如,丢弃一个没有被合并过的分支dev:
$ git branch -D dev

6.查看分支的合并情况:

$ git log --graph --pretty=oneline --abbrev-commit

7.分支策略
在实际开发中,我们应该按照几个基本原则进行分支管理:
首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;
你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。

8.把当前工作现场“储藏”起来,等以后恢复现场后继续工作:

$ git stash

9.查看存储的工作现场

$ git stash list

10.工作现场的恢复

  • git stash apply恢复,但是恢复后,stash内容并不删除(使用git stash list 可看到),你需要用git stash drop来删除
  • git stash pop 恢复的同时把stash内容也删了

11.查看远程库的信息

  • 查看远程库的基本信息
$ git remote
  • 查看远程库详细信息
$ git remote -v

12.推送分支
git push origin <branch name>

  • 推送本地主分支
$ git push origin master
  • 推送其他分支
    如果要推送其他分支,比如dev:
$ git push origin dev

13.抓取分支
$ git checkout -b <local branch name> origin/<remote branch name>

创建远程origin的dev分支到本地:

$ git checkout -b dev origin/dev

将本地分支dev 推送到远程origin的dev分支
git push origin branch-name

$ git push origin dev

14.提交冲突(即推送失败)

  • 先用git pull把最新的提交从origin/dev抓下来,然后,在本地合并,解决冲突,再推送;
  • git pull也失败,原因是没有指定本地dev分支与远程origin/dev分支的链接,根据提示,设置dev和origin/dev的链接:git branch --set-upstream branch-name origin/branch-name
    例如:
$ git branch --set-upstream dev origin/dev

标签

在Git中打标签非常简单,首先,切换到需要打标签的分支上:默认标签是打在最新提交的commit上的。有时候,如果忘了打标签,比如,现在已经是周五了,但应该在周一打的标签没有打,怎么办?方法是找到历史提交的commit id,然后打上就可以了:

1.新建标签

git tag <name>
git tag <name> <commitID>
$ git tag -a <name> -m "descrition" <commitID>

例如:

$ git tag v1.0
$ git tag v0.9 6224937
$ git tag -a v0.1 -m "version 0.1 released" 3628164

2.查看标签
$ git tag 查看所有标签
git show <tagname> 查看标签信息

$ git tag
$ git show v0.9

3.推送本地标签

  • 推送一个本地标签
    git push origin <tagname>
$ git push origin v1.0
  • 推送全部未推送过的本地标签
    git push origin --tags

4.删除标签

  • 删除一个本地标签
    git tag -d <tagname>
$ git tag -d v0.1
  • 删除一个远程标签
    先从本地删除:
$ git tag -d v0.9

再从远程删除。删除命令也是push,但是格式如下:

$ git push origin :refs/tags/v0.9
小结

命令git push origin <tagname>可以推送一个本地标签;
命令git push origin --tags可以推送全部未推送过的本地标签;
命令git tag -d <tagname>可以删除一个本地标签;
命令git push origin :refs/tags/<tagname>可以删除一个远程标签。

参考资料

1.廖雪峰Git教程
2.Git 基本操作 | 菜鸟教程

最后

欢迎大家去 GitHub上Star 和 提Issues,当然,也欢迎留言评论。谢谢大家 !

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

推荐阅读更多精彩内容

  • chapter 1: 如何创建版本库 初始化一个仓库 $ git init 添加文件到Git仓库的过程: $ gi...
    飞将军阅读 2,855评论 0 2
  • 本系列教程来自廖雪峰的官方网站,现在搬运过来,目的帮助自己和小白学习收藏!附赠:常用git命令清单 目录 前言 创...
    Blizzard_liu阅读 1,132评论 0 4
  • 一日黄昏,鼠宝在厨房玩洗碗的海绵,干海绵放在水笼头下冲洗,海绵瞬间充盈起来,此娃挤着手中的海绵说道:时间就如...
    陆陆姐阅读 280评论 0 0
  • 因为k k《失控》大作,影响了一代又一代玩互联网的人,直到现在,《失控》里描述的各种思维和玩儿法仍然适用于现在的互...
    camer阅读 698评论 0 0