1. 简介
Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件
2. GIT和SVN的区别
- GIT是分布式的,SVN不是
还有一些系统,例如Bitkeeper, Mercurial等,也是运行在分布式模式上的。但GIT在这方面做的更好,而且有更多强大的功能特征
分布式模式,如果你被困在一个不能连接网络的地方时,你仍然能够提交文件,查看历史版本记录,创建项目分支等 - GIT把内容按元数据方式存储,而SVN是按文件
.git目录的体积大小跟.svn比较
它拥有中心版本库上所有的东西,例如标签,分支,版本记录等 - GIT分支和SVN的分支不同
- GIT没有一个全局的版本号,而SVN有
- GIT的内容完整性要优于SVN
GIT的内容存储使用的是SHA-1哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏
3. 下载
4. git安装
//Debian/Ubuntu
$ apt-get install git
//Fedora
$ yum install git
//Gentoo
$ emerge --ask --verbose dev-vcs/git
//Arch Linux
$ pacman -S git
//openSUSE
$ zypper install git
//FreeBSD
$ cd /usr/ports/devel/git
$ make install
//Solaris 11 Express
$ pkg install developer/versioning/git
//OpenBSD
$ pkg_add git
5. 用户信息
Git的config命令或者直接编辑~/.gitconfig
这样做很重要,因为每一个Git的提交都会使用这些信息,并且它会写入到你的每一次提交中,不可更改
//git commit 时需要
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
$ git config --list //查看配置
[user]
name = userid
emal = userid@heartsone.net
[color]
status = auto
branch = auto
ui = auto
color在git diff时,显示红色和绿色
6. SSH方式管理
创建一个ssh key
$ ssh-keygen -C 'your@email.address' -t dsa
$ ssh-keygen -C 'your@email.address' -t rsa
/root/.ssh/id_dsa.pub #linux
/c/Users/administrator/.ssh/id_rsa.pub #windows
拷贝id_rsa.pub内的公钥
把公钥添加到git服务器keys中
ssh方式clone
$ git clone ssh://github.com/zwx/test.git
7. https方式管理
GitHub默认就是这种管理方式,直接可以clone
$ git clone https://github.com/zwx/test.git
8. 配置域名解析
c:windowssystem32driversetchosts //windows
/etc/hosts //linux
//添加
192.168.70.130 gerrit.hbu.com
9. 连接成功后
首先要配置name和email,否则,git review时邮箱匹配不上。邮箱需要登录验证
10. git常用命令
$ git init # 初始化Git仓库中所有的必须文件(.git子目录)
#添加
$ git add <file> # 将工作文件修改提交到本地暂存区
$ git add . # 将所有修改过的工作文件提交暂存区
$ git add -f # force
#查看版本库文件列表
$ git ls-files
#查看节点列表(含备注)
$ git show-branch --more=5
#查看提交记录
$ git log <file> # 查看该文件每次提交记录
$ git log -p <file> # 查看每次详细修改内容的diff
$ git log -p -2 # 查看最近两次详细修改内容的diff
#删除
$ git rm <file> # 从版本库中删除文件
$ git rm <file> --cached # 从版本库中删除文件,但不删除文件。适用于一次添加了很多文件, 却又想排除个别几个文件的情况。必须在当前路径
#提交
$ git commit
$ git commit -a # 可以将那些没有通过git add标识的变化一并强行提交,不建议使用这种方式
$ git commit -m "有意义的附加说明"
$ git commit --amend # 新的提交来覆盖上一次的提交
#修改最近一次提交(修改提交附加说明)
$ git commit --amend
#版本库的版本替换工作区的版本
$ git checkout -- file # 撤销file的修改(本地仓库的版本替换工作区的版本)
$ git checkout dir # 撤销dir的修改
$ git checkout * # 撤销所有的修改
#查看diff
$ git diff <file> # 比较当前文件和暂存区文件差异
$ git diff <id1><id2> # 比较两次提交之间的差异
#git远程仓库
$ git remote -v # 查看远程服务器地址和仓库名称
$ git remote add <shortname> <url> # 添加远程仓库地址(可以在命令行中使用字符串shortname来代替url)
$ git remote set-url shortname <repository> # 设置远程仓库地址(用于修改远程仓库地址)(Windows)
$ git remote rm <repository> # 删除远程仓库
#抓取远程仓库
$ git pull = fetch + merge # 抓取远程仓库所有分支更新并合并到本地
$ git fetch shortname # 抓取远程仓库更新。不会自动merge,比Git pull更安全些
使用 clone 命令克隆了一个仓库,命令会自动将其添加为远程仓库并默认以 “origin” 为简写
#推送到远程仓库
$ git push [remote-name] [branch-name]
$ git push origin master
11. review代码
$ pip install git-review
$ git-review
windows安装python,python中有git-review工具;linux直接安装pip
pip安装:http://blog.csdn.net/zhangxuechao_/article/details/46544621
review记录
12. git忽略文件
- .gitignore
.gitignore文件对其所在的目录及所在目录的全部子目录均有效
.gitignore文件可添加到仓库 - .git/info/exclude
只能对自己本地仓库有效 - .git/config
[core]选项,指定忽略规则文件
excludesfile = xx - 忽略规则
?:代表任意的一个字符
*:代表任意数目的字符
[abc]:代表a,b,c中任一字符即可 - 规则举例
忽略*.o和*.a文件
*.[oa]
忽略lib文件和lib目录:
lib
只忽略lib目录
lib/
总结:git忽略以后,git status中的Untracked files将不再显示;当你需要创建一个空目录时,可以在目录里创建一个.gitignore空文件提交
如果发现并未生效,原因是.gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。那么解决方法就是先把本地缓存删除(改变成未track状态),然后再提交
$ git rm -r --cached .
$ git add .
$ git commit -m 'update .gitignore'
13. git分支简介
#当前所有分支
$ git branch -a
* dev # 当前HEAD指针所指向的分支
master
w25q128
remotes/origin/HEAD -> origin/master
remotes/origin/dev # 远程分支
remotes/origin/master
#分支切换
$ git checkout testing # 写入本地分支名,不要写远程分支名(本地dev对应远程remotes/origin/dev)
$ git checkout <SHA> # 下载指定节点(SHA见下图)
#新建分支
$ git checkout -b iss53 # 是下面两条命令的简写
$ git branch iss53
$ git checkout iss53
#分支的合并
$ git merge iss53
#删除不需要的分支
$ git branch -d iss53 //本地
$ git branch -D iss53 //强制删除本地
$ git push origin :iss53 //远程:git push [远程名] :[分支名]
14. git换行符
Windows下开发,建议设置autocrlf为true
UTF8并且包含中文文字,那还是把autocrlf设置为false
Linux/Unix LF
MacOS CR
AutoCRLF
//提交时转换为LF,检出时转换为CR
$ git config --global core.autocrlf true
//提交时转换为LF,检出时不转换
$ git config --global core.autocrlf input
//提交检出均不转换
$ git config --global core.autocrlf false
SafeCRLF
//拒绝提交包含混合换行符的文件
$ git config --global core.safecrlf true
fatal: CRLF would be replaced by LF in readme.txt
//允许提交包含混合换行符的文件
$ git config --global core.safecrlf false
//提交包含混合换行符的文件时给出警告
$ git config --global core.safecrlf warn
warning: CRLF will be replaced by LF in readme.txt.
The file will have its original line endings in your working directory.
15. git编码方式
git gui显示
//utf-8编码显示
$ git config --global gui.encoding utf-8
//ansi编码显示(对于英文文件是ASCII编码,对于简体中文文件是GB2312编码)
$ git config --global gui.encoding ansi
//gbk编码显示
$ git config --global gui.encoding gbk
git 远程仓库默认编码是utf-8
只能看到utf-8编码方式的汉字
16. Git 工具 - 子模块
某个工作中的项目需要包含并使用另一个项目。 也许是第三方库,或者你独立开发的
#添加子模块
$ git submodule add <远程路径> <本地路径/子模块名称> //子模块信息自动添加到.gitmodules和.git/config中
//克隆子模块
$ cat .gitmodules
[submodule "DbConnector"]
path = DbConnector
url = https://github.com/chaconinc/DbConnector
#子模块注册
$ git submodule init <path> //子模块信息自动添加到.git/config
$ cat .git/config
[submodule "modules/uavcan"]
url = https://github.com/ArduPilot/uavcan.git
#删除子模块注册
$ git submodule deinit <path> //子模块信息自动从.git/config删除
#同步子模块url
$ git submodule sync <path> //子模块URL自动更新到.git/config中
#更新子模块
$ git submodule update --init --recursive
#抓取所有子模块提交
$ git submodule foreach git pull
#删除子模块
$ git submodule deinit <path> //删除子模块注册
$ git rm --cached <submodule_name> //删除子模块控制信息
$ vi .gitmodules //删除相应子模块信息
17. 打标签
#打标签
$ git tag # 列出标签
$ git tag -l 'v1.8.5*' # 查找特定标签
#创建附注标签
$ git tag -a v1.4 -m 'my version 1.4'
#创建轻量标签
$ git tag v1.4-lw
$ git show v1.4 # 查看标签信息
#删除标签
$ git tag -d v1.4
#删除远程标签
git push origin :refs/tags/v1.4
#将tag提交到远程仓库
$ git push origin [tagname]
18. 回退
#回退,reset默认参数mixed
$ git reset HEAD <file> # 撤销索引的修改
$ git reset HEAD^ # 撤销最近master HEAD提交
$ git reset HEAD~n # 回退到n次HEAD的提交
$ git reset --soft HEAD^
$ git reset --hard <SHA> # 回退到指定版本的提交
选项 | HEAD | 索引 | 工作目录 |
---|---|---|---|
–soft | 是 | 否 | 否 |
–mixed | 是 | 是 | 否 |
–hard | 是 | 是 | 是 |
soft:可用于修改提交备注
mixed:可用于修改索引信息
hard:直接回退
19. Change-Id错误
remote: ERROR: missing Change-Id in commit message
remote: Suggestion for commit message:
remote: Cosmetic improvements to PostreSQL updater output
remote:
remote: * Don't WARN on sequences already existing
remote: * Align dots nicely to the rest
remote: (cherry picked from commit bd7a268e4be2da23ba0b9943c3b0ba1ac88294dc)
remote:
remote: Change-Id: Ia354acd879c3dd840e7be1e3c6d6fc78d696631d
To ssh://saper@review:29418/mediawiki/core.git
! [remote rejected] HEAD -> refs/for/REL1_19/PostgreSQL (missing Change-Id in commit message)
error: failed to push some refs to 'ssh://saper@review:29418/mediawiki/core.git'
解决办法:
$ git cherry-pick -n bd7a268e4be2da23ba0b9943c3b0ba1ac88294dc
$ git commit -c bd7a268e4be2da23ba0b9943c3b0ba1ac88294dc
remote: Resolving deltas: 100% (1/1)
remote: Processing changes: refs: 1, done
remote: ERROR: missing Change-Id in commit message footer
remote: Suggestion for commit message:
remote: [*][*][*][NA]fix bug[*5]
remote:
remote: Change-Id: I53***80
remote:
remote: Hint: To automatically insert Change-Id, install the hook:
remote: gitdir=$(git rev-parse --git-dir); scp -p -P port name@hostIp:hooks/commit-msg ${gitdir}/hooks/
解决办法:
$ gitdir=$(git rev-parse --git-dir); scp -p -P port name@hostIp:hooks/commit-msg ${gitdir}/hooks/
$ git commit --amend
20. git pull错误
You asked to pull from the remote 'origin', but did not specify
a branch. Because this is not the default configured remote
for your current branch, you must specify a branch on the command line.
解决办法:
# git pull origin master
From github.com:crazyyanchao/SortedNmaePrice
* branch master -> FETCH_HEAD
21. git push错误
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error:
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error:
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
To git@***.***.***.***:/home/git
! [remote rejected] master -> master (branch is currently checked out)
git默认拒绝了push操作
解决办法:
$ .git/config
[receive]
denyCurrentBranch = ignore
22. 冲突处理
<<<<<<< HEAD
test in master
=======
test in dev
>>>>>>> dev
对于简单的合并,手工编辑,然后去掉这些标记,add再commit即可