Git超级简明手册
版本控制系统的历史
版本控制系统,用于协调多个开发者之间的开发。
- CVS----使用文件锁。如果一个人锁定了一个文件,那么其他人就无法修改该文件。
- SVN----集中式版本控制系统。提交之前需要先拉下服务器上的版本,修改冲突后再提交。
- 建立分支依靠本地目录复制。空间利用率低。
- Mercurial----分布式版本控制系统。
- Git----免费的分布式版本控制系统。在BitKeeper不再免费提供给linux项目使用后开发。本地有完整的备份。使用软链接减少内容。
- 建立分支依靠软链接。空间利用率高。
创建git项目
要对现有的某个项目开始用 Git 管理,只需到此项目所在的目录,执行: $ git init 初始化后,在当前目录下会出现一个名为 .git 的目录,所有 Git 需要的数据和资源都存放在这个目录 中。不过目前,仅仅是按照既有的结构框架初始化好了里边所有的文件和目录,但我们还没有开始跟踪管理项 目中的任何一个文件。(在第九章我们会详细说明刚才创建的 .git 目录中究竟有哪些文件,以及都起些什么 作用。) 如果当前目录下有几个文件想要纳入版本控制,需要先用 git add 命令告诉 Git 开始对这些文件进行跟 踪,然后提交: $ git add *.c $ git add README $ git commit -m 'initial project version' 稍后我们再逐一解释每条命令的意思。不过现在,你已经得到了一个实际维护着若干文件的 Git 仓库。
共享git项目
上面,我们已经在本地创建了一个git项目。但有一个问题,其他用户如何访问我们的这个git项目?
纯git仓库
开始架设 Git 服务器的时候,需要把一个现存的仓库导出为新的纯仓库——不包含当前工作目录的仓库。 方法非常直截了当。 把一个仓库克隆为纯仓库,可以使用 clone 命令的 .git 结尾, 如下: $ git clone --bare my_project my_project.git Initialized empty Git repository in /opt/projects/my_project.git/
共享文件夹
最简单的方法,是使用NFS/Samba这样的共享文件系统。 git clone /opt/git/project.git 或者: git clone file:///opt/git/project.git
git clone user@server:project.git
共享用户
可以给每一个用户分配一个git所在计算机上的服务器用户账户,然后使用ssh协议访问。 git clone ssh://user@server:project.git
http服务器
$ cd /var/www/htdocs/ $ git clone --bare /path/to/git_project gitproject.git $ cd gitproject.git $ mv hooks/post-update.sample hooks/post-update $ chmod a+x hooks/post-update
在本例中,我们使用了 Apache 设定中常用的 /var/www/htdocs 路径,不过你可以使用任何静态 web 服务 ——把纯仓库放在它的目录里就行了。
用户可以通过下面的命令来拉取git项目。 git clone http://example.com/gitproject.git 但用户无法通过http提交代码。 http协议也可以提交git代码。但需要假设复杂的webdav服务器。
部署到Github网站
上面各种部署git服务器的方法,都很琐碎,很麻烦。 实际上,现在已经有了不少提供git服务托管的平台。最大的就是github。 https://github.com/explore
github上面有部署了很多开源项目和闭源项目。 github对于开源项目是免费的。对于闭源项目则是收费的。考虑到维护一个git服务器并在internet上可用的成本因素,把公司商业项目存放到github上也是划算的。
部署到gitlab上
公司商业项目,部署到github上,会有一些费用产生。另外,由于代码在github公司的机房上,可能会存在安全问题。 一些公司因此希望把git服务器架设在公司内的服务器上。 gitlab项目,是github的开源选项。用户可以自己搭建gitlab服务器。 gitlab拥有和github一样的完备功能。包括,查看提交,下载文件,wiki,bug和功能跟踪,合并请求等。 除了使用gitlab站点假设git服务器外,还可以把它用作文件、照片、录像等的共享站点。wiki站点。也可以把issue功能用作论坛。基本上可以满足你的所有常用信息共享和交流的需要。限制你的只有你的想象力:) 在gitlab上部署项目很简单。
在gitlab上新建一个git项目:
提交请求后,就会告诉你接下来怎么办。
Command line instructions git config --global user.name "shendl" git config --global user.email "shendl@XXX.cn" mkdir test1 cd test1 git init touch README.md git add README.md git commit -m "first commit" git remote add origin git@gitlab.XXX.cn:shendl/test1.git
git push -u origin master cd existing_git_repo git remote add origin git@gitlab.XXX.cn:shendl/test1.git
git push -u origin master
使用http方式访问,就是: http://gitlab.XXX.cn:80/shendl/test1.git
给项目添加用户:
点击左侧的Settings->Members,可以添加用户,并选择用户访问权限。
生成ssh key并添加到gitlab服务器上,免除每次都要输入密码的麻烦
点击右侧的Profile Settings: 点击ssh key: 可以添加ssh key到gitlab中。这样,你就不需要每次输入用户名和密码了。gitlab服务器会通过ssh key来认证用户。
Ssh key的生成方法:
SSH SSH keys An SSH key allows you to establish a secure connection between your computer and GitLab. Before generating an SSH key, check if your system already has one by running cat ~/.ssh/id_rsa.pub. If you see a long string starting with ssh-rsa or ssh-dsa, you can skip the ssh-keygen step.
To generate a new SSH key, just open your terminal and use code below. The ssh-keygen command prompts you for a location and filename to store the key pair and for a password. When prompted for the location and filename, you can press enter to use the default. It is a best practice to use a password for an SSH key, but it is not required and you can skip creating a password by pressing enter. Note that the password you choose here can't be altered or retrieved. ssh-keygen -t rsa -C "shendl@XXX.cn" Use the code below to show your public key. cat ~/.ssh/id_rsa.pub Copy-paste the key to the 'My SSH Keys' section under the 'SSH' tab in your user profile. Please copy the complete key starting with ssh- and ending with your username and host. Use code below to copy your public key to the clipboard. Depending on your OS you'll need to use a different command: Windows: clip < ~/.ssh/id_rsa.pub Mac: pbcopy < ~/.ssh/id_rsa.pub GNU/Linux (requires xclip): xclip -sel clip < ~/.ssh/id_rsa.pub Deploy keys Deploy keys allow read-only access to multiple projects with a single SSH key. This is really useful for cloning repositories to your Continuous Integration (CI) server. By using deploy keys, you don't have to setup a dummy user account. If you are a project master or owner, you can add a deploy key in the project settings under the section 'Deploy Keys'. Press the 'New Deploy Key' button and upload a public SSH key. After this, the machine that uses the corresponding private key has read-only access to the project. You can't add the same deploy key twice with the 'New Deploy Key' option. If you want to add the same key to another project, please enable it in the list that says 'Deploy keys from projects available to you'. All the deploy keys of all the projects you have access to are available. This project access can happen through being a direct member of the project, or through a group. See def accessible_deploy_keys in app/models/user.rb for more information.
生成ssh key后,添加到gitlab中:
git常用技巧
好了,现在我们已经有了便于访问的git服务器,大家可以一起协作使用git进行开发了。
git和http方式的区别
gitlab服务器,支持git和http两种访问协议。 如果使用http方式访问,则每次都需要输入gitlab的用户名和密码进行用户身份认证。 如果使用git方式访问,并且已经提交了ssh key到gitlab服务器,则无需输入用户名和密码即可使用git。 另外,对于大文件,http访问可能会上传或者下载失败。此时只能使用git方式。 git方式: git remote add origin git@10.10.100.47:shendl/test1.git http方式: git remote add origin http://gitlab.XXX.cn:80/shendl/test1.git
从git项目得到纯代码
我们要分发git项目的代码时,不希望把git文件也一起发出去。这时可以使用如下命令: git archive master --prefix='project/' | gzip >git describe master.tar.gz master可以改成其他分支名。
生成用于部署服务器的纯git项目
$ git clone --bare my_project my_project.git
添加.gitignore文件
在git项目的根目录下,新建一个.gitignore文件,用于决定忽略添加一些本地文件到git服务器上。 git add .gitignore -f 把这个.gitignore文件添加到git服务器上。 临时文件,编译生成的文件,本地项目配置文件,不应该提交到git服务器上。否则会造成重复,还会影响其他用户的开发环境。
添加文件到git版本控制下
git add README.md 我们可以使用 git add ./ 添加所有文件。
提交到本地git版本控制下
git commit -m "first commit" git commit -a 会弹出一个编辑器,让你编写注释
提交本地改变到git远程服务器上
git push -u origin master origin是远程git服务器默认名。master是本地git的默认分支名。
Git push不会提交tag到服务器上,需要执行下列命令,才能把tag推送到服务器上。 git push --tags
拉取远程服务器的最新改变到本地
git pull
查看本地仓库的修改状态
git status
查看提交
Git log 这里的log,就是 git commit -m "first commit" git commit -a 会弹出一个编辑器,让你编写注释 中编写的注释
git log -p 查看每次提交的差异。
查看标签
git tag
添加标签
git tag -a v1.6.0-3 在当前提交上创建一个tag,并添加注释
查看标签详情
git tag -v v1.0.0-2 object f94c91da7345153f7623eae82a253d40f6dc8832 type commit tag v1.0.0-2 tagger shendl shendl@XXX.cn 1443519901 +0800
版本v1.0.0-2 error: no signature found error: 不能校验 tag 'v1.0.0-2'
你可以根据散列码,找到对应的git log中的提交项目。
删除本地标签
git tag -d v1.7.0-11
推送本地标签到远程
git push --tags
删除远程标签
如果远程已经存在与本地同名的标签但是内容不同,则推送会失败。此时需要删除远程标签。命令如下: git push origin --delete tag v1.7.0-11
得到版本号
git describe master v1.0.0-2 再做一次提交后,再次执行 git describe master v1.0.0-2-1-g438d372
v1.0.0-2-1是最近一次打的tag,438d372是最近一次提交的散列码的前7位。通过这个版本号,可以找到对应的git的提交。 查看分支 git branch
- master
默认是master分支。
创建并切换到新分支
git checkout -b test 切换到一个新分支 'test'
切换到已有的分支
git checkout master 切换到分支 'master' 您的分支与上游分支 'origin/master' 一致。
丢弃未提交的修改
有时,我们做了一些修改,最后发现修改错了。我们希望直接丢弃这些修改。 git stash 文件会恢复到之前的状态。 注意:只有git add file添加后的文件,commit之前的改变,才会被git stash丢弃
git stash pop 命令,可以恢复被丢弃的更改。
回滚到某个提交的状态
Git log 查看提交历史,找出对应的hash编码 git checkout 438d372b1d07b1210add0c98af00f3f765553218 就可以回到该历史状态。
但此时已经不在任何分支中,因此无法提交代码。 如果希望在这个状态开始提交代码,则需要使用 git branch -b branchName 在此基础上创建一个新的分支。
回滚到某个tag的状态
Git tag 查看提交 Git checkout tag名称 其他和回滚到某个提交的语法一样。
取消某次提交
Git log查看提交 git revert 1bb71333ca72f99158c7f1ea805fa70abc9416a7 这会进行一次新的提交,内容就是取消对应提交的内容。
再次git log,可以看到添加了一次新的提交。
回复到某次提交,并丢弃后续所有提交
Git log查看提交 git reset 1bb71333ca72f99158c7f1ea805fa70abc9416a7 这回回复到该提交的状态,并丢弃后续所有提交。
再次git log,可以该提交后的log都没了。 被删除的内容,实际上被扔在了git stash中。 可以使用git stash pop命令,把删除的内容恢复回来。
重命名文件
git mv old new
删除文件
git rm file
Git子模块
子模块允许你将一个 Git 仓库作为另一个 Git 仓库的子目录。 它能让你将另一个仓库克隆到自己的项目中,同时还保持提交的独立。 git submodule add URL [localDir]
给项目添加一个子模块 如 git submodule add git@10.10.100.47:shendl/qtCommon.git
或者 git submodule add git@10.10.100.47:shendl/qtCommon.git qtCommon 提交代码后,项目就拥有了子模块。 子模块表现为项目的一个子目录。 项目的git命令不会影响子模块。 进入到子模块,可以执行完整的git命令。
随后需要 git add ./ git commit -a git push 推送这个更改到服务器。
其他客户端 git clone URL 或者git pull 拉到源代码,此时,子模块目录下没有内容。 执行: git submodule init 会执行初始化子模块 git submodule update 下载子模块的最新源代码到本地。 每次子模块代码更新时,需要执行git submodule update下载最新的源代码到本地。或者也可以cd 子模块目录,然后执行git pull获取源代码。
注意: 子模块,通常用来引用第三方项目的某一个稳定版本的代码或者分支。 在子模块中,最好不要修改代码。而是另外作为一个独立的git项目把该子模块下载下来,进行开发和提交。 在包含子模块的项目中,只执行git submodule update 命令下载最新的代码。因为git submodule update命令会下载项目最新代码并直接覆盖掉本地代码。因此不应该在子模块中修改代码。 如果一定要在子模块中修改代码,可以在子模块中新建一个分支,在该独立分支中开发,最后与项目代码进行分支合并或者子树合并。
gitTools
gitTools是一个开源项目,用于提供帮助简化git日常使用的工具。
gitPullSubdir.py
gitPullSubdir.py是gitTools包中的一个实用工具程序。使用它可以遍历指定目录下所有子目录,执行git pull,拉去最新代码。使用这个工具,可以帮助你快速更新所有git项目。 gitPullSubdir.py -i XXX 遍历拉取指定目录下所有子目录的git项目的最新源码。
PS:本文pdf版本,可以在如下地址下载:Git超级简明手册pdf版