目录
14、创建和切换到新的分支git checkout -b branchname
16、删除分支:git branch -d branchname
1、获取配置列表:git config --list
2、获取帮助提示:git help
3、初始化git目录:git init
该命令将创建一个名为 .git
的子目录,这个子目录含有你初始化的 Git 仓库中所有的必须文件,这些文件是 Git 仓库的骨干。 但是,在这个时候,我们仅仅是做了一个初始化的操作,你的项目里的文件还没有被跟踪。 (参见 Git 内部原理 来了解更多关于到底 .git
文件夹中包含了哪些文件的信息。)
4、克隆仓库:git clone
如果你想获得一份已经存在了的 Git 仓库的拷贝,比如说,你想为某个开源项目贡献自己的一份力,这时就要用到 git clone
命令。 如果你对其它的 VCS 系统(比如说 Subversion)很熟悉,请留心一下你所使用的命令是"clone"而不是"checkout"。 这是 Git 区别于其它版本控制系统的一个重要特性,Git 克隆的是该 Git 仓库服务器上的几乎所有数据,而不是仅仅复制完成你的工作所需要文件。 当你执行 git clone
命令的时候,默认配置下远程 Git 仓库中的每一个文件的每一个版本都将被拉取下来。 事实上,如果你的服务器的磁盘坏掉了,你通常可以使用任何一个克隆下来的用户端来重建服务器上的仓库 (虽然可能会丢失某些服务器端的钩子(hook)设置,但是所有版本的数据仍在)。
如果你想在克隆远程仓库的时候,自定义本地仓库的名字,你可以通过额外的参数指定新的目录名:
$ git clone https://github.com/libgit2/libgit2 mylibgit
Git 支持多种数据传输协议。 上面的例子使用的是 https://
协议,不过你也可以使用 git://
协议或者使用 SSH 传输协议,比如 user@server:path/to/repo.git
5、检查当前文件状态:git status
可以用 git status
命令查看哪些文件处于什么状态。 如果在克隆仓库后立即使用此命令,会看到类似这样的输出:
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
6、跟踪新文件:git add
使用命令 git add
开始跟踪一个文件。 所以,要跟踪 README
文件,运行:
$ git add README
git add
命令使用文件或目录的路径作为参数;如果参数是目录的路径,该命令将递归地跟踪该目录下的所有文件。
7、提交文件到仓库:git commit
$ git commit -m "wrote a readme file"
[master (root-commit) eaadf4e] wrote a readme file
1 file changed, 2 insertions(+)
create mode 100644 readme.txt
简单解释一下git commit
命令,-m
后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。
嫌麻烦不想输入-m "xxx"
行不行?确实有办法可以这么干,但是强烈不建议你这么干,因为输入说明对自己对别人阅读都很重要。实在不想输入说明的童鞋请自行Google,我不告诉你这个参数。
git commit
命令执行成功后会告诉你,1 file changed
:1个文件被改动(我们新添加的readme.txt文件);2 insertions
:插入了两行内容(readme.txt有两行内容)。
为什么Git添加文件需要add
,commit
一共两步呢?因为commit
可以一次提交很多文件,所以你可以多次add
不同的文件,比如:
$ git add file1.txt
$ git add file2.txt file3.txt
$ git commit -m "add 3 files."
8、查看提交日志:git log
D:\gitlearn>git log
commit 145244faeafcdca1f31b113cbc115ebfc7db786a (HEAD -> master)
Author: tangbohu9527 <zhouke6901@163.com>
Date: Mon Jun 8 14:57:25 2020 +0800
the third commit
commit 2d26e6fbef066055a491d7776cdefa63df4a8a1b
Author: tangbohu9527 <zhouke6901@163.com>
Date: Mon Jun 8 14:54:05 2020 +0800
second commit
commit 813c5668e69f61c28e32b5a8f429c2ce4bbe10c7
Author: tangbohu9527 <zhouke6901@163.com>
Date: Mon Jun 8 14:45:00 2020 +0800
this is a describ mesg\
git log
命令显示从最近到最远的提交日志,我们可以看到3次提交。
如果嫌输出信息太多,看得眼花缭乱的,可以试试加上--pretty=oneline
参数:
D:\gitlearn>git log --pretty=oneline
145244faeafcdca1f31b113cbc115ebfc7db786a (HEAD -> master) the third commit
2d26e6fbef066055a491d7776cdefa63df4a8a1b second commit
813c5668e69f61c28e32b5a8f429c2ce4bbe10c7 this is a describ mesg\
需要友情提示的是,你看到的一大串类似1094adb...
的是commit id
(版本号),和SVN不一样,Git的commit id
不是1,2,3……递增的数字,而是一个SHA1计算出来的一个非常大的数字,用十六进制表示,而且你看到的commit id
和我的肯定不一样,以你自己的为准。为什么commit id
需要用这么一大串数字表示呢?因为Git是分布式的版本控制系统,后面我们还要研究多人在同一个版本库里工作,如果大家都用1,2,3……作为版本号,那肯定就冲突了。
9、版本回退:git reset
a,回退版本
首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD
表示当前版本,也就是最新的提交1094adb...
(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^
,上上一个版本就是HEAD^^
,当然往上100个版本写100个^
比较容易数不过来,所以写成HEAD~100
。
现在,我们要把当前版本append GPL
回退到上一个版本add distributed
,就可以使用git reset
命令:
D:\gitlearn>git reset --hard HEAD~1
HEAD is now at 2d26e6f second commit
现在使用git log查看当前状态:
D:\gitlearn>git log
commit 2d26e6fbef066055a491d7776cdefa63df4a8a1b (HEAD -> master)
Author: tangbohu9527 <zhouke6901@163.com>
Date: Mon Jun 8 14:54:05 2020 +0800
second commit
commit 813c5668e69f61c28e32b5a8f429c2ce4bbe10c7
Author: tangbohu9527 <zhouke6901@163.com>
Date: Mon Jun 8 14:45:00 2020 +0800
this is a describ mesg\
最新的那个版本the third commit
已经看不到了!好比你从21世纪坐时光穿梭机来到了19世纪,想再回去已经回不去了,肿么办?
办法其实还是有的,只要上面的命令行窗口还没有被关掉,你就可以顺着往上找啊找啊,找到那个the third commit
的commit id
是145244...
,于是就可以指定回到未来的某个版本:
D:\gitlearn>git reset --hard 145244
HEAD is now at 145244f the third commit
b、回退已提交到暂存区的代码。
Git同样告诉我们,用命令git reset HEAD <file>
可以把暂存区的修改撤销掉(unstage),重新放回工作区。
修改文件,并git add:
D:\gitlearn>git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: readme.txt
这里,我们先修改下readme文件,然后git add到暂存区,这时候你又不想提交了怎么办,就用:
D:\gitlearn>git reset head readme.txt
Unstaged changes after reset:
M readme.txt
D:\gitlearn>git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
这时,添加到暂存区的文件,又被回退到工作区了。
如果我们想恢复文件到最新的commit的文件用:
D:\gitlearn>git checkout -- readme.txt
D:\gitlearn>git status
On branch master
nothing to commit, working tree clean
10:记录命令git reflog
现在,你回退到了某个版本,关掉了电脑,第二天早上就后悔了,想恢复到新版本怎么办?找不到新版本的commit id
怎么办?
在Git中,总是有后悔药可以吃的。当你用$ git reset --hard HEAD^
回退到上一个
版本时,再想恢复到其他版本
,就必须找到append GPL
的commit id。Git提供了一个命令git reflog
用来记录你的每一次命令。然后找到你的提交记录,找到commit id,就可以使用你上一次的git reset --hard 145244了。
D:\gitlearn>git reflog
145244f (HEAD -> master) HEAD@{0}: reset: moving to 145244
2d26e6f HEAD@{1}: reset: moving to HEAD~1
145244f (HEAD -> master) HEAD@{2}: commit: the third commit
2d26e6f HEAD@{3}: commit: second commit
813c566 HEAD@{4}: commit (initial): this is a describ mesg\
11、文件删除git rm file
在Git中,删除也是一个修改操作,我们实战一下,先添加一个新文件test.txt
到Git并且提交。
然后用git rm test.txt删除文件
D:\gitlearn>git rm test.txt
rm 'test.txt'
D:\gitlearn>git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: test.txt
然后commit
D:\gitlearn>git commit -m "rm test.txt"
[master 50cb5d6] rm test.txt
1 file changed, 1 deletion(-)
delete mode 100644 test.txt
回复办法如果已经提交到了暂存区,还没有commit,就用git checkout -- test.txt;如果已经commit了,则可以使用git reset --hard commitid 来恢复。
12、与远程仓库建立链接:
$ git remote add origin git@github.com:tangbohu9527/learngit.git
要关联一个远程库,使用命令git remote add origin git@server-name:path/repo-name.git
;
关联后,使用命令git push -u origin master
第一次推送master分支的所有内容;
此后,每次本地提交后,只要有必要,就可以使用命令git push origin master
推送最新修改;
分布式版本系统的最大好处之一是在本地工作完全不需要考虑远程库的存在,也就是有没有联网都可以正常工作,而SVN在没有联网的时候是拒绝干活的!当有网络的时候,再把本地提交推送一下就完成了同步,真是太方便了!
13、把本地代码上传push到远程仓库:git push
$ git push -u origin master
Counting objects: 20, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (15/15), done.
Writing objects: 100% (20/20), 1.64 KiB | 560.00 KiB/s, done.
Total 20 (delta 5), reused 0 (delta 0)
remote: Resolving deltas: 100% (5/5), done.
To github.com:michaelliao/learngit.git
* [new branch] master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
由于远程库是空的,我们第一次推送master
分支时,加上了-u
参数,Git不但会把本地的master
分支内容推送的远程新的master
分支,还会把本地的master
分支和远程的master
分支关联起来,在以后的推送或者拉取时就可以简化命令。
从现在起,只要本地作了提交,就可以通过命令:
$ git push origin master
把本地master
分支的最新修改推送至GitHub,现在,你就拥有了真正的分布式版本库!
14、创建和切换到新的分支git checkout -b branchname
首先,我们创建dev
分支,然后切换到dev
分支:
$ git checkout -b dev
Switched to a new branch 'dev'
git checkout
命令加上-b
参数表示创建并切换,相当于以下两条命令:
$ git branch dev
$ git checkout dev
Switched to branch 'dev'
然后,用git branch
命令查看当前分支:
$ git branch
* dev
master
git branch
命令会列出所有分支,当前分支前面会标一个*
号。
switch
我们注意到切换分支使用git checkout <branch>
,而前面讲过的撤销修改则是git checkout -- <file>
,同一个命令,有两种作用,确实有点令人迷惑。
实际上,切换分支这个动作,用switch
更科学。因此,最新版本的Git提供了新的git switch
命令来切换分支:
创建并切换到新的dev
分支,可以使用:
$ git switch -c dev
直接切换到已有的master
分支,可以使用:
$ git switch master
使用新的git switch
命令,比git checkout
要更容易理解。
15、合并分支git merge branchname
现在,我们把dev
分支的工作成果合并到master
分支上:
$ git merge dev
Updating d46f35e..b17d20e
Fast-forward
readme.txt | 1 +
1 file changed, 1 insertion(+)
git merge
命令用于合并指定分支到当前分支。合并后,再查看readme.txt
的内容,就可以看到,和dev
分支的最新提交是完全一样的。
注意到上面的Fast-forward
信息,Git告诉我们,这次合并是“快进模式”,也就是直接把master
指向dev
的当前提交,所以合并速度非常快。
当然,也不是每次合并都能Fast-forward
,我们后面会讲其他方式的合并。
合并完成后,就可以放心地删除dev
分支了:
$ git branch -d dev
Deleted branch dev (was b17d20e).
删除后,查看branch
,就只剩下master
分支了:
$ git branch
* master
因为创建、合并和删除分支非常快,所以Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在master
分支上工作效果是一样的,但过程更安全。
通常,合并分支时,如果可能,Git会用Fast forward
模式,但这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用Fast forward
模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
$ git merge --no-ff -m "merge with no-ff" branchname
16、删除分支:git branch -d branchname
合并完成后,就可以放心地删除dev
分支了:
$ git branch -d dev
Deleted branch dev (was b17d20e).
删除后,查看branch
,就只剩下master
分支了:
$ git branch
* master
因为创建、合并和删除分支非常快,所以Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在master
分支上工作效果是一样的,但过程更安全。
17、合并冲突时候怎么办
当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。
解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交。
用git log --graph
命令可以看到分支合并图。
git log --graph --pretty=oneline --abbrev-commit
18、git stash命令
git stash会把当前工作区修改的内容保存到一个地方,然后工作区会暂时忽略掉你所修改的东西,此时,git status命令将会提示branch is clean。这个时候,你可以放心的去切换另一个分支,修改另一个需要修改的地方,然后提交。另一个工作做好了,再切换回来。
D:\gitskills\gitskills>git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
(use "git push" to publish your local commits)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: README.md
no changes added to commit (use "git add" and/or "git commit -a")
D:\gitskills\gitskills>git stash
Saved working directory and index state WIP on master: 1d6fc9b meger with no-ff
D:\gitskills\gitskills>git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
bug解决后,此时,我又想继续做之前的工作了,怎么办 。切回之前的分支,然后运行git stash list,查看之前stash在了那里。
D:\gitskills\gitskills>git stash list
stash@{0}: WIP on master: 1d6fc9b meger with no-ff
工作现场还在,Git把stash内容存在某个地方了,但是需要恢复一下,有两个办法:
一是用git stash apply
恢复,但是恢复后,stash内容并不删除,你需要用git stash drop
来删除;
另一种方式是用git stash pop
,恢复的同时把stash内容也删了:
$ git stash pop
On branch dev
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: hello.py
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
Dropped refs/stash@{0} (5d677e2ee266f39ea296182fb2354265b91b3b2a)
再用git stash list
查看,就看不到任何stash内容了:
$ git stash list
你可以多次stash,恢复的时候,先用git stash list
查看,然后恢复指定的stash,用命令:
$ git stash apply stash@{0}