参考:Pro Git, 常用git命令清单, git简明指南, 猴子都能懂的git教程
git是分布式版本控制系统,每个客户端都保存了整个代码仓库,在本地对文件进行修改后,保存在暂存区域,之后提交更新,最后推送到远端git仓库,在此过程中,只有推送需要连接网络,因此,git对版本控制的操作并不依赖网络,便于保持数据的完整性和版本历史的洁净。
$ sudo apt-get install git
初次运行git之前需要配置一些参数和变量,包括/etc/gitconfig
、~/.gitconfig
或~/.config/git/config
以及当前使用仓库git目录中的.git/config
,这三个文件中,后一个配置会覆盖上一级别的配置。
$ git config -e --global # 编辑 ~/.gitconfig
$ git config -e # 编辑 .git/config
也可以在shell中直接编辑配置文件。
$ git config --global user.name "Tom King"
$ git config --global user.email uuspider@gmail.com
git会把用户名和email写入每一次版本提交,并且不可更改。这里--global
选项是针对全系统设置的,如果针对特定项目使用不同用户名和email时,就不要使用该选项。
git默认使用vim,如果想使用emacs,可以这样配置:
$ git config --global core.editor emacs
git可以彩色显示:
$ git config --global color.ui auto
还可以为git命令设定别名,如将checkout
缩略为co
等:
$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status
$ git config --list # 查看所有配置
$ git config user.name # 查看指定项配置,这里是查看用户名
$ git help config
[TOP]
将当前目录(workspace)所有文件导入git:
$ git init
该命令创建一个.git
子目录,初始化git仓库(repository)所有的必须文件,如果指定project-name,即git init <project-name>
,就新建一个目录并初始化为git仓库。
$ git add *.py
$ git add templates static
git add <file-name/dir-name>
将文件快照添加到暂存区(stage或index),git add .
表示将当前目录(workspace)所有文件快照加入暂存区,-p
会提示文件快照变化并要求确认。
$ git rm readme.txt
从workspace删除文件。
$ git rm --cached license.txt
不再将文件添加到stage,但保留在workspace。
$ git mv readme README
重命名workspace中的文件名并记录在stage。
$ git commit -m 'commit message'
git commit
是将暂存区快照提交到本地git仓库(HEAD),-m
后可输入代码提交的说明信息,--amend -m 'commit mesage'
是修改最后一次commit
说明信息,--amend <file-name>
重复最后一次commit
,-a
表示将workspace快照直接提交到HEAD,-v
显示所有diff信息。
$ git status
查看当前git仓库的状态。
$ git log
$ git log -5 --stat
查看git日志。
使用clone
可将远端服务器上git仓库所有文件和版本信息都复制到本地:
$ git clone https://github.com/USERNAME/repo.git LocalGitName
git支持ssh、git等协议,如:
$ git clone ssh://git@github.com:22/USERNAME/repo.git
建立git仓库后,就可以在本地管理和编辑工作文件,然后推送到远端。
[TOP]
完成工作文件的编辑后,可使用add
和commit
提交本次更新到本地git仓库:
$ git add *.py
$ git commit -m 'commit message'
如果是将当前目录所有文件快照都加入仓库,即git add .
,则上述这两条命令可以合并处理:
$ git commit -a -m 'commit message'
如果远端服务器已经存在当前git仓库,可以直接使用push
将本地git仓库的更新推送过去:
$ git push origin master
其格式为git push -u <remote-name> <branch-name>
,注意如果指定了-u
选项,此后的推送便可以省略’remote-name’和’branch-name’,首次运行时不可省略。’origin’和’master’是习惯用法,分别为远端git仓库和主分支的默认名称。
$ git remote
列出远端git仓库名称。
$ git remote -v
列出远端git仓库名称与其对应的url。
$ git remote show origin
通过git remote show [remote-name]
,可以查看远端仓库url和分支信息,如果不指定remote-name,可以列出更多信息。
如果远端git仓库有更新,可以使用pull
将其同步到本地git仓库:
$ git pull origin master
执行push
或pull
时,如果省略远端git仓库名称,则默认其为origin。
[TOP]
多人协作或多模块协作任务(主分支,merge分支)过程中,每个成员或每个模块的修改记录可以分别保存,形成一个个分支任务(topic分支),各个分支的编辑、修改不受其他分支影响,当完成该分支任务后,按照一定的逻辑合并到主分支,这就是git的核心功能。
$ git branch
列出所有本地分支,-r
列出所有fetch
到本地的远程分支,-a
列出所有本地分支和fetch
到本地的远程分支。
$ git branch bugfix
创建bugfix分支,但HEAD仍指向原分支。要切换到bugfix分支,需使用checkout
:
$ git checkout bugfix
切换分支后,HEAD指向bugfix,工作目录中的文件会随之改变。
如果需要新建分支并马上切换到新的分支,可以使用checkout
的-b
选项:
$ git checkout -b hurryfix
如果要将本地分支与指定远端分支建立追踪关系,可以使用--set-upstream
:
$ git branch --set-upstream hurryfix origin/serverfix
也可以在远端分支的基础上,在本地新建分支:
$ git checkout hurryfix origin/serverfix
origin/serverfix
是fetch
到本地的远程分支表示形式,指远端origin仓库中的serverfix分支。
完成hurryfix任务后,可切换回上一个分支:
$ git checkout -
如果上一个分支为master,就可以把hurryfix合并到master:
$ git merge hurryfix
如果hurryfix和bugfix同步进行,对同一个文件的同一部分做了不同的修改,git合并分支时就会引起冲突(conflicts),此时,可以使用git status
查看冲突解决标记或git diff <branch_a> <branch_b>
查看差异,然后在workspace修改含有冲突内容的文件,使用git add
将该冲突文件标记为已解决,最后完成git commit
并再次合并分支。
被合并到master后,hurryfix分支就可以删除了:
$ git branch -d hurryfix
git branch
还有一些其它选项,如-v
可以列出最后一次提交,--merged
和--no-merged
可分别列出已经合并和未合并到当前分支的分支,-vv
则可以列出所有本地分支的更多信息,同时列出与远端分支进行版本信息的比较结果。
注意:上述所有操作均在本地操作。
在本地处理git协作任务时,需要查看远端git仓库及其分支信息:
$ git remote -v
$ git ls-remote
列出远端origin仓库信息:
$ git remote show origin
如果远端服务器还没有建立相应的git仓库(remote),可使用remote add
将本地git仓库推送过去:
$ git remote add remote-name git@github.com:USERNAME/repo.git # 这是ssh协议的一种写法
远端’remote-name’可以这样修改:
$ git remote rename remote-name origin
通过push
可以将本地完成的分支任务推送到远端:
$ git push origin master
这条命令表示将本地master分支推送到远端origin仓库,并命名为master分支,如果远端分支的名称需要修改为bugfix,可以这样做:
$ git push origin master:bugfix
表示推送本地master分支来更新远端origin仓库上的bugfix分支。
如果其他协作者在远端origin仓库中建立了一个serverfix分支,可以fetch
到本地:
$ git fetch origin serverfix
或者将origin的所有更新都fetch
到本地:
$ git fetch origin
但此时本地的serverfix分支并不能编辑,如果需要在这个新的serverfix分支上进行工作,需要checkout
:
$ git checkout -b origin/serverfix
这个操作有一个快捷方式:
$ git checkout --track origin/serverfix
表示在本地新建一个serverfix分支,并与远端origin/serverfix建立追踪关系。
如果需要为本地分支与远端分支设置不同名称,可以:
$ git checkout -b sf origin/serverfix
$ git checkout --track sf origin/serverfix
再回到pull
,pull
实际上是fetch
+merge
,即将远端分支fetch
到本地仓库,然后再merge
到相应的本地分支,如:
$ git fetch origin
$ git merge origin/serverfix:master
可以写成:
$ git pull origin serverfix:master
表示fetch
远程origin仓库的serverfix分支,同时与本地当前仓库master分支合并。如果是与当前分支合并,则这里的master可以省略;如果当前分支与远程分支存在追踪关系,则远程分支名可以省略;如果当前仓库只有一个追踪分支,则远程git仓库名也可以省略,即:
$ git pull
当远程git仓库删除某个分支后,pull
不会删除对应的本地分支,如果需要同步删除对应的本地分支,可以使用-p
选项。
当完成一个分支任务的所有工作后,就可以将该分支合并到远端master分支,然后删除该分支,删除远端分支:
$ git push origin --delete serverfix
或
$ git remote rm serverfix
分支的合并,除了merge
,还有rebase
,rebase
和merge
的最终结果是一样的,其优点在于提交记录更加清晰,如在topic分支中更新master分支的更新,就可以使用rebase
简化记录,而向master分支导入topic分支,可先rebase
,再merge
,如:
$ git checkout hurryfix
$ git reabse master
$ git checkout master
$ git merge hurryfix
[TOP]
通常,正式发布的软件都拥有版本号,与此类似,git支持为提交的记录添加标签:
$ git tag 0.1.0 1234567890
末尾的十位十六进制数字是所要标记的commit的前十位,如果不提供则表示标记当前的commit。commit ID可以通过log
查看:
$ git log
列出所有tag:
$ git tag
删除本地tag:
$ git tag -d [tag]
删除远端tag:
$ git push origin :refs/tags/[tagName]
查看tag信息:
$ git show [tag]
提交指定tag:
$ git push [remote_branch] [tag]
提交所有tag:
$ git push [remote_branch] --tags
新建一个分支,指向某个tag:
$ git checkout -b [branch] [tag]
[TOP]
安装git后,创建一个git用户:
$ sudo adduser git_pi
选定一个目录作为git仓库,如/srv/pi.git
,在/srv
目录下输入:
$ sudo git init --bare pi.git
修改用户权限,禁止用户直接登录服务器修改工作区:
$ sudo chown -R git_pi:git_pi pi.git
编辑/etc/passwd
,禁止git用户登录shell,找到:
git_pi:x:1001:1001:,,,:/home/git:/bin/bash
改为:
git_pi:x:1001:1001:,,,:/home/git:/usr/bin/git-shell
git服务器搭建完成,现在可在客户端使用git命令了,如:
$ git clone git_pi@192.168.1.99:/srv/pi.git
[TOP]