Git入门教程

Git是一个分布式版本控制软件,最初由林纳斯·托瓦兹创作,于2005年以GPL发布。最初目的是为更好地管理Linux内核开发而设计。

新建文件夹

1
2
mkdir learngit
cd learngit

设置文件夹为Git可以管理的仓库

1
git init

查看隐藏的文件

1
ls -ah

新建一个readme.txt文本文件,再将Git文件夹下面的文件添加到仓库。

1
git add readme.txt

用命令git commit告诉Git,把文件提交到仓库

1
git commit -m "wrote a readme file"

使用git status命令,时刻查看git的状态

1
git status

使用git diff readme.txt命令,查看文本的更改情况

1
2
3
4
5
6
7
8
9
10
11
$ git diff readme.txt
diff --git a/readme.txt b/readme.txt
index e69de29..5367626 100644
--- a/readme.txt
+++ b/readme.txt
@@ -0,0 +1,2 @@
+Git is a distributed version control system.
+Git is a free software.
warning: LF will be replaced by CRLF in readme.txt.
The file will have its original line endings in your working directory.

  1. 一般来说,修改文件之后在add之前马上使用git diff才能看到区别
  2. add提交之后再使用diff就不能看到区别了
  3. add之前使用git status看到的是修改文件是红色的
  4. add之后使用git status看到的是修改文件是绿色的
  5. commit之后再使用git status就看不到变化了

使用git log --pretty=oneline查看修改情况

1
2
3
4
5
6
7
8
9
10
$ git log --pretty=oneline
9e86558600d190136a1b109dff14f70587b0c11a modify tow line
afd2594462a539056a88b978f1062d02f54e3bfb add a line
86905b5f5584d902eb78fd1d589bc8fbddccfd66 remove distribute
47a40c4bb05c2ac81c56148e0135aef78defc219 fisrt modify
f8f397cb4868fd77a08cffb8e6b277fe8f0eee5c remove distirbute
432d801fe7c3720a8ca5a4b52eb83ba7272a5760 Change the discription
e7facd5759491dcefdb73b4b2cd004d71fd72645 Change the discription
3ea98a88c081d219804cb661a46d3349b1bd44df wrote a readme file

使用命令git reset --hard HEAD^返回上一个版本

1
2
$ git reset --hard HEAD^
HEAD is now at afd2594 add a line

在窗口未关闭的情况下,查看之前各个版本的commit id再使用git reset --hard commitID命令就可以返回对应的版本了。

1
2
$ git reset --hard HEAD^
HEAD is now at afd2594 add a line

在窗口关闭的情况下,使用git reflog命令查看之前的各个版本的commitID,再使用git reset --hard commitID命令就可以返回对应的版本了。

1
2
3
4
5
6
7
8
9
10
11
12
$ git reflog
9e86558 HEAD@{0}: reset: moving to 9e86558600d190136a1b109dff14f70587b0c11a
afd2594 HEAD@{1}: reset: moving to HEAD^
9e86558 HEAD@{2}: commit: modify tow line
afd2594 HEAD@{3}: commit: add a line
86905b5 HEAD@{4}: commit: remove distribute
47a40c4 HEAD@{5}: commit: fisrt modify
f8f397c HEAD@{6}: commit: remove distirbute
432d801 HEAD@{7}: commit: Change the discription
e7facd5 HEAD@{8}: commit: Change the discription
3ea98a8 HEAD@{9}: commit (initial): wrote a readme file

如果不add到暂存区,那就不会加入到commit中。

使用Git命令丢弃修改

  • git checkout -- readme.txt命令撤销工作区的修改
  • 命令git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:
    • 一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
    • 一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Tony@Tony-PC MINGW64 /e/gitrepository/learngit (master)
$ git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
#modified: readme.txt还存在
deleted: readme
modified: readme.txt
modified: test.txt

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

#使用git checkout -- readme.txt命令
Tony@Tony-PC MINGW64 /e/gitrepository/learngit (master)
$ git checkout -- readme.txt

Tony@Tony-PC MINGW64 /e/gitrepository/learngit (master)
$ git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
#使用git checkout -- readme.txt, modified: readme.txt记录就消失了
deleted: readme
modified: test.txt

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

用命令git reset HEAD file可以把提交到暂存区的修改撤销掉,重新放回工作区。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
Tony@Tony-PC MINGW64 /e/gitrepository/learngit (master)
$ git add readme.txt


Tony@Tony-PC MINGW64 /e/gitrepository/learngit (master)
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
#修改已经提交了
modified: readme.txt

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

deleted: readme
modified: test.txt

#用命令git reset HEAD file可以把提交到暂存区的修改撤销掉(unstage),重新放回工作区
Tony@Tony-PC MINGW64 /e/gitrepository/learngit (master)
$ git reset HEAD readme.txt
Unstaged changes after reset:
D readme
M readme.txt
M test.txt

#提交到缓存区的修改已经被撤销了
Tony@Tony-PC MINGW64 /e/gitrepository/learngit (master)
$ git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

deleted: readme
modified: readme.txt
modified: test.txt

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

场景应对

场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file。中间是两个-

场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file,就回到了场景1,第二步按场景1操作。

场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考版本回退一节,不过前提是没有推送到远程库。

Git命令撤销删除

使用rm -rf filename命令删除文件之后,有两个选择:

1、确实要从版本库中删除该文件,那就用命令git rm删掉,并且git commit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Tony@Tony-PC MINGW64 /e/gitrepository/learngit (master)
$ git rm test.txt
rm 'test.txt'

Tony@Tony-PC MINGW64 /e/gitrepository/learngit (master)
$ git commit -m"delete test.txt"
[master 381a470] delete test.txt
1 file changed, 6 deletions(-)
delete mode 100644 test.txt

Tony@Tony-PC MINGW64 /e/gitrepository/learngit (master)
$ git status
On branch master
nothing to commit, working directory clean

现在,文件就从版本库中被删除了。

这时候你要恢复就只能使用 git reset --hard HEAD^

2、你只是在误删文件,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本。

1
2
3
4
5
6
7
8
Tony@Tony-PC MINGW64 /e/gitrepository/learngit (master)
$ git checkout -- test.txt

Tony@Tony-PC MINGW64 /e/gitrepository/learngit (master)
$ ll
total 2
-rw-r--r-- 1 Tony 197121 81 七月 11 10:23 readme.txt
-rw-r--r-- 1 Tony 197121 172 七月 11 11:00 test.txt

这样文件删除就直接恢复了 需要注意的是删除操作提交到缓冲区之后是不能回撤到工作区的,必须再git rm filename+git commit -m" ",然后再版本回退,git reset --hard HEAD^。

远程仓库

1、创建SHH Key

1
$ ssh-keygen -t rsa -C "youremail@example.com"

2、 在Github上添加SSHKey
点击设置,然后将为sshkey取名字,将刚刚生成的id_rsa.pub的内容复制到Github的设置界面,点击确认之后就能得到SSHkey了。

3、新建一个名为learngit的repository
在GitHub上新建一个repository,默认设置。

4、将本地的git库关联到Github上的码仓
注意输入正确的码仓地址git@github.com:TonyDandelion/learngit.git,TonyDandelion是独一无二的GitHub名字。

1
$ git remote add origin git@github.com:TonyDandelion/learngit.git
5、将本地的文件push到Github上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Tony@Tony-PC MINGW64 /e/gitrepository/learngit (master)
$ git push -u origin master
The authenticity of host 'github.com (192.30.253.113)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no)? y
Please type 'yes' or 'no': yes
Warning: Permanently added 'github.com,192.30.253.113' (RSA) to the list of known hosts.
Counting objects: 38, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (35/35), done.
Writing objects: 100% (38/38), 3.22 KiB | 0 bytes/s, done.
Total 38 (delta 11), reused 0 (delta 0)
To git@github.com:TonyDandelion/learngit.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.

由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。

6、只要本地做了修改,使用命令$ git push origin master就能把本地master分支的最新修改推送至GitHub!

小结
要关联一个远程库,使用命令git remote add origin git@server-name:path/repo-name.git;
关联后,使用命令git push -u origin master第一次推送master分支的所有内容;
此后,每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改;

远程库的克隆

只有用ssh方式连接,才能获取修改权限。

1
2
3
4
5
6
#ssh方式连接
git clone git@git.coding.net:quseitlab/tianjin1che.git
git clone git@github.com:TonyDandelion/gitskills.git

#https方式连接
#git clone https://git.coding.net/quseitlab/tianjin1che.git

实例

1
2
3
4
5
6
7
Tony@Tony-PC MINGW64 /e/gitrepository
$ git clone git@github.com:TonyDandelion/gitskills.git
Cloning into 'gitskills'...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done.
Checking connectivity... done.

要克隆一个仓库,首先必须知道仓库的地址,然后使用git clone命令克隆。
Git支持多种协议,包括https,但通过ssh支持的原生git协议速度最快。
生成shh公钥

1
ssh-keygen -t rsa

分支管理

1、建立分支并且切换

1
2
$ git checkout -b dev
Switched to a new branch 'dev'

git checkout命令加上-b参数表示创建并切换,相当于以下两条命令:

1
2
3
$ git branch dev
$ git checkout dev
Switched to branch 'dev'

2、使用git branch来查看当前的分支

1
2
3
$ git branch
* dev
master

3、在当前分支下修改文本文件

1
2
3
4
Tony@Tony-PC MINGW64 /e/gitrepository/gitskills (master)
$ cat README.md
# gitskills
Creating a new branch is quick
4、操作完成,切回master。

1
2
3
4
5
6
7
8
9
Tony@Tony-PC MINGW64 /e/gitrepository/gitskills (dev)
$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.

Tony@Tony-PC MINGW64 /e/gitrepository/gitskills (master)
$ git branch
dev
* master

5、将在dev上做的修改一起整合到master

1
2
3
4
5
6
7
8
9
10
11
Tony@Tony-PC MINGW64 /e/gitrepository/gitskills (master)
$ git merge dev
Updating e9c4711..9b2d797
Fast-forward
README.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

Tony@Tony-PC MINGW64 /e/gitrepository/gitskills (master)
$ cat README.md
# gitskills
Creating a new branch is quick

git merge命令用于合并指定分支到当前分支。合并后,再查看readme.txt的内容,就可以看到,和dev分支的最新提交是完全一样的。

6、合并修改之后就能直接删除分支了

1
2
3
4
5
6
7
8
Tony@Tony-PC MINGW64 /e/gitrepository/gitskills (master)
$ git branch -d dev
Deleted branch dev (was 9b2d797).

#这时查看分支就只有一个分支了
Tony@Tony-PC MINGW64 /e/gitrepository/gitskills (master)
$ git branch
* master

7、总结
Git鼓励大量使用分支:
查看分支:git branch
创建分支:git branch
切换分支:git checkout
创建+切换分支:git checkout -b
合并某分支到当前分支:git merge
删除分支:git branch -d

参考链接:廖雪峰


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!