git 指引

参考: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日志。

将远端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]


更新仓库

完成工作文件的编辑后,可使用addcommit提交本次更新到本地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仓库更新同步到本地

如果远端git仓库有更新,可以使用pull将其同步到本地git仓库:

$ git pull origin master

执行pushpull时,如果省略远端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/serverfixfetch到本地的远程分支表示形式,指远端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

再回到pullpull实际上是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,还有rebaserebasemerge的最终结果是一样的,其优点在于提交记录更加清晰,如在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后,创建一个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]