Git使用(Windows)
下载、安装
从https://git-for-windows.github.io下载msysgit,然后按默认选项安装。
安装完成后,在开始菜单里找到“Git”->“Git Bash”,蹦出一个类似命令行窗口的东西,就说明Git安装成功!
安装完成后,设置本机标示,在命令行输入:
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
--globle设置参数为git全局范围有效,所有仓库都用这个标示,也可对单个仓库进行设置
创建版本库repository
选择合适地方创建一个空目录:
$ mkdir learngit
$ cd learngit
$ pwd #pwd命令用于显示当前目录
/Users/michael/learngit
。这个仓库位于/Users/michael/learngit。
如果使用Windows系统,为了避免遇到各种莫名其妙的问题,请确保目录名(包括父目录)不包含中文。
通过git init命令把这个目录变成Git可以管理的仓库:
$ git init
Initialized empty Git repository in /Users/michael/learngit/.git/
完成后,目录下会多出一个.git的隐藏目录,可用ls -ah查看,别修改这个目录内文件
添加文件到版本库
在仓库目录下创建文件并编辑后保存,如创建readme.txt
Git is a version control system.
Git is free software.
使用git add命令添加文件到版本库
$ git add readme.txt
执行后没有任何提示就对了
使用git commit命令提交文件到仓库
$ git commit -m "Add a file:readme.txt"
[master (root-commit) cb926e7] Add a file:readme.txt
1 file changed, 2 insertions(+)
create mode 100644 readme.txt
git commit命令,-m后面输入的是本次提交的说明描述文字,可多次add后一次整体commit
查看文件状态
成功提交eadme.txt文件后,修改下readme.txt内容:
Git is a distributed version control system.
Git is free software.
运行git status命令看看结果:
$ 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")
git status命令可以让我们时刻掌握仓库当前的状态,上面的命令告诉我们,readme.txt被修改过了,但还没有准备提交的修改。
使用git diff查看修改内容
$ git diff readme.txt
diff --git a/readme.txt b/readme.txt
index 46d49bf..9247db6 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.
查看后确定可以提交,一样的步骤add、commit
$ git add readme.txt
执行第二步git commit之前,我们再运行git status看看当前仓库的状态:
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: readme.txt
#
git status告诉我们,将要被提交的修改包括readme.txt,下一步,就可以放心地提交了:
$ git commit -m "Line1 add a word"
[master ea34578] Line1 add a word
1 file changed, 1 insertion(+), 1 deletion(-)
提交后,我们再用git status命令看看仓库的当前状态:
$ git status
# On branch master
nothing to commit (working directory clean)
Git告诉我们当前没有需要提交的修改,而且,工作目录是干净(working directory clean)的。
版本回退
重复上面的操作,修改readme后提交
Git is a distributed version control system.
Git is free software distributed under the GPL.
$ git add readme.txt
$ git commit -m "Line2 add some words"
[master 3628164] Line2 add some words
1 file changed, 1 insertion(+), 1 deletion(-)
经过上面几次提交后,现在版本库变成下面的样子
使用git log命令查看从近到远的提交日志
$ git log
commit fda52802b4551da74d7af6404619f658a69655a6
Author: look <630201142@qq.com>
Date: Wed Oct 19 15:16:37 2016 +0800
Line2 add some words
commit fed45af4b99f94ab56c3c3a16ede85c1bcf751f0
Author: look <630201142@qq.com>
Date: Wed Oct 19 15:12:17 2016 +0800
Line1 add a word
commit 5b49080152c968a2858e30a50bddee469bb301e7
Author: look <630201142@qq.com>
Date: Wed Oct 19 14:57:20 2016 +0800
Add a file:readme.txt
可加上参数--pretty=oneline查看精简版日志
$ git log --pretty=oneline
bdfa566022b19ff334fb82fabdb3848b2f6b7bd9 Line2 add some words
fed45af4b99f94ab56c3c3a16ede85c1bcf751f0 Line1 add a word
5b49080152c968a2858e30a50bddee469bb301e7 Add a file:readme.txt
每次提交生成的一大串数字就是commitID,用于标记本次提交,
在Git中,用HEAD表示当前版本,也就是最新的提交fda52802b4551da74d7af6404619f658a69655a6 ,上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。现在,回退到上一个版本“Line1 add a word”,就可以使用git reset命令:
$ git reset --hard HEAD^
HEAD is now at fed45af Line1 add a word
查看readme的内容,已经变成上一版本的了:
$ cat readme.txt
Git is a distributed version control system.
Git is free software.
还可以继续回退到上一个版本,不要急,先用git log看一下版本库:
$ git log
commit fed45af4b99f94ab56c3c3a16ede85c1bcf751f0
Author: look <630201142@qq.com>
Date: Wed Oct 19 15:12:17 2016 +0800
Line1 add a word
commit 5b49080152c968a2858e30a50bddee469bb301e7
Author: look <630201142@qq.com>
Date: Wed Oct 19 14:57:20 2016 +0800
Add a file:readme.txt
最新的那个版本已经没了!没了!!真的没了!!!怎么办,我还想要呢?别急,我们的黑窗口还在呢,找到最新版本的commitID,直接通过ID恢复即可,ID只写前几位就行了:
$ git reset --hard bdfa
HEAD is now at bdfa566 Line2 add some words
$ git log --pretty=oneline
bdfa566022b19ff334fb82fabdb3848b2f6b7bd9 Line2 add some words
fed45af4b99f94ab56c3c3a16ede85c1bcf751f0 Line1 add a word
5b49080152c968a2858e30a50bddee469bb301e7 Add a file:readme.txt
OK,世界依旧很美好^_^
但是,刚才我要是关了这个黑窗口,或者关机了,我怎么知道这个commitID呢,别急,有办法:
$ git reflog
bdfa566 HEAD@{0}: reset: moving to bdfa
fed45af HEAD@{1}: reset: moving to HEAD^
bdfa566 HEAD@{2}: commit: Line2 add some words
fed45af HEAD@{3}: reset: moving to HEAD^
fda5280 HEAD@{4}: commit: Line add some words
fed45af HEAD@{5}: commit: Line1 add a word
5b49080 HEAD@{6}: commit (initial): Add a file:readme.txt
看到了吧,git reflog会列出所有操作记录
Git版本回退速度非常快,因为他内部有一个HEAD指针,回退时直接移动指针指向的位置,同时更新文件。
管理修改
Git跟踪并管理的是修改,而非文件。什么是修改?比如你新增了一行,这就是一个修改,删除了一行,也是一个修改,更改了某些字符,也是一个修改,删了一些又加了一些,也是一个修改,甚至创建一个新文件,也算一个修改。 为什么说Git管理的是修改,而不是文件呢?我们还是做实验。第一步,对readme.txt做一个修改,比如加一行内容:
$ cat readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes.
然后,添加:
$ git add readme.txt
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: readme.txt
#
然后,再修改readme.txt:
$ cat readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
提交:
$ git commit -m "git tracks changes"
[master d4f25b6] git tracks changes
1 file changed, 1 insertion(+)
提交后,再看看状态:
$ 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")
咦,怎么第二次的修改没有被提交?别激动,我们回顾一下操作过程:
第一次修改 -> git add -> 第二次修改 -> git commit
我们前面讲了,Git管理的是修改,当你用git add命令后,在工作区的第一次修改被放入暂存区,准备提交,但是,在工作区的第二次修改并没有放入暂存区,所以,git commit只负责把暂存区的修改提交了,也就是第一次的修改被提交了,第二次的修改不会被提交。
提交后,用git diff HEAD -- readme.txt命令可以查看工作区和版本库里面最新版本的区别:
$ git diff HEAD -- readme.txt
diff --git a/readme.txt b/readme.txt
index 76d770f..a9c5755 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,4 +1,4 @@
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
-Git tracks changes.
+Git tracks changes of files.
可见,第二次修改确实没有被提交。
那怎么提交第二次修改呢?你可以继续git add再git commit,也可以别着急提交第一次修改,先git add第二次修改,再git commit,就相当于把两次修改合并后一块提交了
撤销修改
命令git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:
一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit或git add时的状态。
git checkout -- file命令中的--很重要,没有--,就变成了“切换到另一个分支”的命令
如果修改后add到了缓存区但还没有commit到版本库,可以用命令git reset HEAD file可以把暂存区的修改撤销掉(unstage),重新放回工作区
git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的版本。
删除文件
一般情况下,你通常直接在文件管理器中把没用的文件删了,或者用rm命令删了:
$ rm test.txt
这个时候,Git知道你删除了文件,因此,工作区和版本库就不一致了,git status命令会立刻告诉你哪些文件被删除了:
$ 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: test.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
现在你有两个选择,一是确实要从版本库中删除该文件,那就用命令git rm删掉,并且git commit:
$ git rm test.txt
rm 'test.txt'
$ git commit -m "remove test.txt"
[master d17efd8] remove test.txt
1 file changed, 1 deletion(-)
delete mode 100644 test.txt
现在,文件就从版本库中被删除了。
另一种情况是删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本:
$ git checkout -- test.txt
git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
远程仓库(github为例)
第1步:注册github,创建SSH Key
在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步。如果没有,打开Shell(Windows下打开Git Bash),创建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文件的内容,点“Add Key”,你就应该看到已经添加的Key
为什么GitHub需要SSH Key呢?因为GitHub需要识别出你推送的提交确实是你推送的,而不是别人冒充的,而Git支持SSH协议,所以,GitHub只要知道了你的公钥,就可以确认只有你自己才能推送。当然,GitHub允许你添加多个Key。假定你有若干电脑,你一会儿在公司提交,一会儿在家里提交,只要把每台电脑的Key都添加到GitHub,就可以在每台电脑上往GitHub推送了。
第3步:创建远程仓库并关联本地仓库
创建成功后github会给出提示,可以关联本地库并推送到远程库
现在,关联远程库
$ git remote add origin git@github.com:lookDev/learngit.git
下一步,就可以用git push把本地库的所有内容推送到远程库上:
$ git push -u origin master
Counting objects: 19, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (19/19), done.
Writing objects: 100% (19/19), 13.73 KiB, done.
Total 23 (delta 6), reused 0 (delta 0)
To git@github.com:michaelliao/learngit.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
用git push命令,实际上是把当前分支master推送到远程。由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。
推送成功后,可以立刻在GitHub页面中看到远程库的内容已经和本地一模一样,从现在起,只要本地作了提交,就可以通过命令:
$ git push origin master
把本地master分支的最新修改推送至GitHub,现在,你就拥有了真正的分布式版本库!
取消本地目录下关联的远程库:
git remote remove origin
从远程库克隆
上次我们讲了先有本地库,后有远程库的时候,如何关联远程库。现在,假设我们从零开发,那么最好的方式是先创建远程库,然后,从远程库克隆。
首先,登陆GitHub,创建一个新的仓库,名字叫gitskills,我们勾选Initialize this repository with a README,这样GitHub会自动为我们创建一个README.md文件。现在,远程库已经准备好了,下一步是用命令git clone克隆一个本地库:
$ git clone git@github.com:michaelliao/gitskills.git
Cloning into 'gitskills'...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.
$ cd gitskills
$ ls
README.md
创建与合并分支
创建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命令会列出所有分支,当前分支前面会标一个*号。
然后,我们就可以在dev分支上正常提交
切换回master分支:
$ git checkout master
Switched to branch 'master'
我们把dev分支的工作成果合并到master分支上:
$ git merge dev
Updating d17efd8..fec145a
Fast-forward
readme.txt | 1 +
1 file changed, 1 insertion(+)
git merge命令用于合并指定分支到当前分支
注意到上面的Fast-forward信息,Git告诉我们,这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。当然,也不是每次合并都能Fast-forward,我们后面会讲其他方式的合并。
合并完成后,就可以放心地删除dev分支了:
$ git branch -d dev
Deleted branch dev (was fec145a).
删除后,查看branch,就只剩下master分支了:
$ git branch
* master
Git鼓励大量使用分支:
查看分支:git branch
创建分支:git branch <name>
切换分支:git checkout <name>
创建+切换分支:git checkout -b <name>
合并某分支到当前分支:git merge <name>
删除分支:git branch -d <name>
合并时冲突问题及解决
合并时产生冲突会有CONFLICT提示,然后冲突文件就会被加上冲突标记,类似:
a123
<<<<<<< HEAD
b789
=======
b45678910
>>>>>>> 6853e5ff961e684d3a6c02d4d06183b5ff330dcc
c
其中:冲突标记<<<<<<< (7个<)与=======之间的内容是我的修改,=======与>>>>>>>之间的内容是别人的修改。
此时,还没有任何其它垃圾文件产生。
最简单的编辑冲突的办法,就是直接编辑冲突了的文件(test.txt),把冲突标记删掉,把冲突解决正确,如果冲突地方很多,也可以使用图形化界面处理,使用git mergetool命令打开合并工具处理完保存并标记冲突解决即可
启动Beyond Compare之后,会自动生成几个包含大写字母名称、数字的辅助文件:
关闭Beyond Compare时,这几个辅助文件都会自动删除,但同时会生成一个test.txt.orig的文件,内容是解决冲突前的冲突现场。默认该.orig文件可能不会自动删除,需要手动删掉。
冲突解决完毕后,需要使用git add、git commit提交修改后就可以push操作了。
使用git log --graph --pretty=oneline --abbrev-commit查看合并情况
$ git log --graph --pretty=oneline --abbrev-commit
* 2cb41c8 合并冲突解决
|\
| * e21bacb 分支上修改dev.txt
* | 103b278 主分支也修改了dev.txt
|/
* 32e0f77 创建分支,添加dev.txt
* bd23d49 移除分支文件
* ebba678 创建分支dev,添加txt文件
* bdfa566 Line2 add some words
* fed45af Line1 add a word
* 5b49080 Add a file:readme.txt
通常,合并分支时,如果可能(没有冲突产生),Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。合并时加上--no-ff参数,不使用快速合并模式,则提交时会有合并记录,推荐使用noff模式(有冲突时默认就不是ff模式了,会有合并记录产生)
Bug分支
场景:正在dev分支进行开发任务,突然接到修复bug101的任务,必须马上修复,当前任务还没完成又不能提交,怎么办?使用git stash命令保存当前分支工作信息
$ git stash
Saved working directory and index state WIP on b1: e21bacb 分支上修改dev.txt
HEAD is now at e21bacb 分支上修改dev.txt
然后查看工作区状态就是clean的了,可以放心切换到master分支并新建bug分支干活了
ke@Lenovo-PC MINGW64 /d/java/git-rep/learngit (b1)
$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
ke@Lenovo-PC MINGW64 /d/java/git-rep/learngit (master)
$ git checkout -b bug101
Switched to a new branch 'bug101'
ke@Lenovo-PC MINGW64 /d/java/git-rep/learngit (bug101)
$ git add dev.txt
ke@Lenovo-PC MINGW64 /d/java/git-rep/learngit (bug101)
$ git commit -m "修复bug101"
[bug101 eb9ef1f] 修复bug101
1 file changed, 4 insertions(+), 1 deletion(-)
修复后切回master合并bug101提交,删除bug101,push
$ git merge bug101 --no-ff -m "修复bug101"
Merge made by the 'recursive' strategy.
dev.txt | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
修复完成,切换工作分支继续工作,先git status看下状态,什么,什么都没了?怎么回到之前stash的状态呢?
用git stash list命令看看:
$ git stash list
stash@{0}: WIP on b1: e21bacb 分支上修改dev.txt
OK,还在,怎么恢复呢?
一是用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除;
另一种方式是用git stash pop,恢复的同时把stash内容也删了:
$ git stash pop
On branch b1
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: dev.txt
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (22a6f4d60b78dff8d716c613dc07f8de96a8a87c)
可多次stash,先用git stash list查看,后用$ git stash apply stash@{0}恢复指定stash
开发新功能时,创建分支开发,之后合并主分支即可,如果开发完成合并前需要取消开发任务,也就是删除功能分支,需要使用git branch -D xx强制删除,用-d会提示还未合并。
多人协作
当你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin。 要查看远程库的信息,用git remote或者用git remote -v显示更详细的信息:
$ git remote
origin
ke@Lenovo-PC MINGW64 /d/java/git-rep/learngit (master)
$ git remote -v
origin git@github.com:lookDev/learngit (fetch)
origin git@github.com:lookDev/learngit (push)
上面显示了可以抓取和推送的origin的地址。如果没有推送权限,就看不到push的地址。
模拟另一用户,在另一目录clone仓库下来,设置user.name和user.email指定另一个github用户即可(email区分),add、commit后push。之前的用户再次push前需要先通过git pull把远程更改同步到本地进行合并后才能push。
多人协作的工作模式通常是这样:
首先,可以试图用git push origin branch-name推送自己的修改;
如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;
如果合并有冲突,则解决冲突,并在本地提交;
没有冲突或者解决掉冲突后,再用git push origin branch-name推送就能成功!
如果git pull提示“no tracking information”,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream branch-name origin/branch-name。
这就是多人协作的工作模式,一旦熟悉了,就非常简单。
标签管理
在Git中打标签非常简单,首先,切换到需要打标签的分支上:
$ git branch
* dev
master
$ git checkout master
Switched to branch 'master'
然后,敲命令git tag <name>就可以打一个新标签:
$ git tag v1.0
可以用命令git tag查看所有标签:
$ git tag
v1.0
默认标签是打在最新提交的commit上的。有时候,如果忘了打标签,比如,现在已经是周五了,但应该在周一打的标签没有打,怎么办?方法是找到历史提交的commit id,然后打上就可以了:
$ git log --pretty=oneline --abbrev-commit
6a5819e merged bug fix 101
cc17032 fix bug 101
7825a50 merge with no-ff
6224937 add merge
59bc1cb conflict fixed
400b400 & simple
75a857c AND simple
fec145a branch test
d17efd8 remove test.txt
...
比方说要对add merge这次提交打标签,它对应的commit id是6224937,敲入命令:
$ git tag v0.9 6224937
注意,标签不是按时间顺序列出,而是按字母排序的。可以用git show <tagname>查看标签信息
还可以创建带有说明的标签,用-a指定标签名,-m指定说明文字:
$ git tag -a v0.1 -m "version 0.1 released" 3628164
如果标签打错了,也可以删除:
$ git tag -d v0.1
Deleted tag 'v0.1' (was e078af9)
因为创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。
如果要推送某个标签到远程,使用命令git push origin <tagname>:
$ git push origin v1.0
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:michaelliao/learngit.git
* [new tag] v1.0 -> v1.0
或者,一次性推送全部尚未推送到远程的本地标签:
$ git push origin --tags
Counting objects: 1, done.
Writing objects: 100% (1/1), 554 bytes, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@github.com:michaelliao/learngit.git
* [new tag] v0.2 -> v0.2
* [new tag] v0.9 -> v0.9
如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:
$ git tag -d v0.9
Deleted tag 'v0.9' (was 6224937)
然后,从远程删除。删除命令也是push,但是格式如下:
$ git push origin :refs/tags/v0.9
To git@github.com:michaelliao/learngit.git
- [deleted] v0.9
Git配置
让Git显示颜色,会让命令输出看起来更醒目:
$ git config --global color.ui true
忽略特殊文件
有些时候,你必须把某些文件放到Git工作目录中,但又不能提交它们,比如保存了数据库密码的配置文件啦,等等,每次git status都会显示Untracked files ...,有强迫症的童鞋心里肯定不爽。好在Git考虑到了大家的感受,这个问题解决起来也很简单,在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。不需要从头写.gitignore文件,GitHub已经为我们准备了各种配置文件,只需要组合一下就可以使用了。所有配置文件可以直接在线浏览:https://github.com/github/gitignore
配置别名
有没有经常敲错命令?比如git status?status这个单词真心不好记。如果敲git st就表示git status那就简单多了,当然这种偷懒的办法我们是极力赞成的。我们只需要敲一行命令,告诉Git,以后st就表示status:
$ git config --global alias.st status
当然还有别的命令可以简写,很多人都用co表示checkout,ci表示commit,br表示branch:
$ git config --global alias.co checkout
$ git config --global alias.ci commit
$ git config --global alias.br branch
以后提交就可以简写成:
$ git ci -m "bala bala bala..."
--global参数是全局参数,也就是这些命令在这台电脑的所有Git仓库下都有用。
在撤销修改一节中,我们知道,命令git reset HEAD file可以把暂存区的修改撤销掉(unstage),重新放回工作区。既然是一个unstage操作,就可以配置一个unstage别名:
$ git config --global alias.unstage 'reset HEAD'
当你敲入命令:
$ git unstage test.py
实际上Git执行的是:
$ git reset HEAD test.py
配置一个git last,让其显示最后一次提交信息:
$ git config --global alias.last 'log -1'
这样,用git last就能显示最近一次的提交
甚至还有人丧心病狂地把lg配置成了:
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
配置文件
配置Git的时候,加上--global是针对当前用户起作用的,如果不加,那只针对当前的仓库起作用。
配置文件放哪了?每个仓库的Git配置文件都放在.git/config文件中:
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[remote "origin"]
url = git@github.com:michaelliao/learngit.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[alias]
last = log -1
别名就在[alias]后面,要删除别名,直接把对应的行删掉即可。
而当前用户的Git配置文件放在用户主目录下的一个隐藏文件.gitconfig中:
$ cat .gitconfig
[alias]
co = checkout
ci = commit
br = branch
st = status
[user]
name = Your Name
email = your@email.com
搭建Git服务器
搭建Git服务器需要准备一台运行Linux的机器,强烈推荐用Ubuntu或Debian,这样,通过几条简单的apt命令就可以完成安装。假设你已经有sudo权限的用户账号,下面,正式开始安装。
第一步,安装git:
$ sudo apt-get install git
第二步,创建一个git用户,用来运行git服务:
$ sudo adduser git
第三步,创建证书登录:
收集所有需要登录的用户的公钥,就是他们自己的id_rsa.pub文件,把所有公钥导入到/home/git/.ssh/authorized_keys文件里,一行一个。
第四步,初始化Git仓库:
先选定一个目录作为Git仓库,假定是/srv/sample.git,在/srv目录下输入命令:
$ sudo git init --bare sample.git
Git就会创建一个裸仓库,裸仓库没有工作区,因为服务器上的Git仓库纯粹是为了共享,所以不让用户直接登录到服务器上去改工作区,并且服务器上的Git仓库通常都以.git结尾。然后,把owner改为git:
$ sudo chown -R git:git sample.git
第五步,禁用shell登录:
出于安全考虑,第二步创建的git用户不允许登录shell,这可以通过编辑/etc/passwd文件完成。找到类似下面的一行:
git:x:1001:1001:,,,:/home/git:/bin/bash
改为:
git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell
这样,git用户可以正常通过ssh使用git,但无法登录shell,因为我们为git用户指定的git-shell每次一登录就自动退出。
第六步,克隆远程仓库:
现在,可以通过git clone命令克隆远程仓库了,在各自的电脑上运行:
$ git clone git@server:/srv/sample.git
Cloning into 'sample'...
warning: You appear to have cloned an empty repository.
管理公钥
如果团队很小,把每个人的公钥收集起来放到服务器的/home/git/.ssh/authorized_keys文件里就是可行的。如果团队有几百号人,就没法这么玩了,这时,可以用Gitosis来管理公钥。
https://github.com/res0nat0r/gitosis
问题解决
Git-bash中有时一屏显示不下时会出现END标记,无法输入命令的情况,按q键即可