GIT分布式版本控制系统

1. 简介

Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件

2. GIT和SVN的区别

  1. GIT是分布式的,SVN不是
    还有一些系统,例如Bitkeeper, Mercurial等,也是运行在分布式模式上的。但GIT在这方面做的更好,而且有更多强大的功能特征
    分布式模式,如果你被困在一个不能连接网络的地方时,你仍然能够提交文件,查看历史版本记录,创建项目分支等
  2. GIT把内容按元数据方式存储,而SVN是按文件
    .git目录的体积大小跟.svn比较
    它拥有中心版本库上所有的东西,例如标签,分支,版本记录等
  3. GIT分支和SVN的分支不同
  4. GIT没有一个全局的版本号,而SVN有
  5. GIT的内容完整性要优于SVN
    GIT的内容存储使用的是SHA-1哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏

3. 下载

https://git-scm.com/downloads

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中

公钥
1
ssh方式clone

$ git clone ssh://github.com/zwx/test.git

7. https方式管理

GitHub默认就是这种管理方式,直接可以clone

$ git clone https://github.com/zwx/test.git

8. 配置域名解析

c:\windows\system32\drivers\etc\hosts		//windows
/etc/hosts									//linux

//添加
192.168.70.130 gerrit.hbu.com

9. 连接成功后

首先要配置name和email,否则,git review时邮箱匹配不上。邮箱需要登录验证
settings

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记录
review

12. git忽略文件

  1. .gitignore
    .gitignore文件对其所在的目录及所在目录的全部子目录均有效
    .gitignore文件可添加到仓库
  2. .git/info/exclude
    只能对自己本地仓库有效
  3. .git/config
    [core]选项,指定忽略规则文件
    excludesfile = xx
  4. 忽略规则
    ?:代表任意的一个字符
    *:代表任意数目的字符
    [abc]:代表a,b,c中任一字符即可
  5. 规则举例
    忽略*.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 [远程名] :[分支名]

1

14. git换行符

Windows下开发,建议设置autocrlf为true
UTF8并且包含中文文字,那还是把autocrlf设置为false

Linux/Unix	LF	\n
MacOS		CR	\r

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编码方式的汉字
1

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即可

参考:https://git-scm.com/book/zh/v2

posted @ 2015-06-16 20:58  thomas_blog  阅读(128)  评论(0编辑  收藏  举报