个人Blog: hhktony.com
全部博文(553)
分类: LINUX
2013-01-13 20:27:46
gnu interactive tools
一句话概括git: Git is at its heart very stupid simple!
SHA-1哈希值:40个十六进制字符(0-9 及 a-f),它唯一确定一个文件
SCM:soucre control management
$ sudo apt-get install git-core tig
$ sudo yum install git-core
(/etc/gitconfig、~/.gitconfig、.git/config)
类UNIX下软件的配置方式基本上都有两种:用命令、修改配置文件
以下是以本地用户基于命令的配置方式如果想学git这种最原始的方式还是需要掌握的,
当然了你也可以直接修改配置文件来达到相同的效果。
$ git config --global user.name "username" $ git config --global user.email username@mail.com
$ git config --global core.editor vim
$ git config --global merge.tool meld
$ git config --global alias.co checkout # `co`将会成为`checkout`的别名
$ git config --list # 查看所有配置信息 $ git config user.name # 查看用户名配置信息 $ cat ~/.gitconfig # 查看配置文件内容
$ git init
$ git add filename
$ git add .
$ git commit -m "msg"
$ git status
$ git log $ git log -p -2 # 查看最近两次提交并显示修改内容
$ git branch branch_name
$ git checkout branch_name
小技巧: 以上两步可以合并成一步
$ git checkout -b branch_name # 创建分支并进入新建的分支
$ git merge branch_name
$ git branch -d branch_name
对于任何一个文件,在Git内都只有三种状态:
已提交(committed):表示该文件已经被安全地保存在本地数据库中了
已修改(modified):表示修改了某个文件,但还没有提交保存
已暂存(staged):表示把已修改的文件放在下次提交时要保存的清单中
在工作目录中修改某些文件
对修改后的文件进行快照,然后保存到暂存区域
提交更新,将保存在暂存区域的文件快照永久转储到Git目录中
如果是Git目录中保存着的特定版本文件,就属于已提交状态
如果作了修改并已放入暂存区域,就属于已暂存状态
如果自上次取出后,作了修改但还没有放到暂存区域,就是已修改状态
未跟踪
跟踪
查看尚未暂存的更改与暂存区内容的差异(不会被提交)
$ git diff [filename]
查看已经暂存起来的文件和上次提交的版本之间的差异(下次提交的内容)
$ git diff --staged(或cached) [filename]
查看工作目录与上次提交时之间的所有差别
$ git diff HEAD
查看某两个版本之间的差异
$ git diff ffd98[:filename] b8e7b0[:filename]
这个命令就不多做讲解了,试试各个命令的显示效果,选一个自己喜欢的即可
$ git log $ git log -2 $ git log -p $ git log -p -2 $ git log git log -p --author="butbueatiful" $ git log --pretty=oneline $ git log --graph $ git log --pretty=format:'%h : %s' --graph $ git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative
$ git commit -m "提交的描述信息"
注意: 如果我们这里不用-m参数的话,Git将调到一个文本编译器(默认是nano)来让你输入提交的描述信息,如果按照我们之前的设置应该是vim。
另外 在.bashrc中加入export EDITOR="vim"也可以达到这种效果,区别在于使用这种方式所有软件的默认编辑器都会变成vim,当然软件自己的配置优先级更高。
$ git commit -a -m "提交的描述信息" 或 $ git commit -am "提交的描述信息"
说明: -a选项可只将所有被修改或者已删除的且已经被Git追踪的文档提交倒仓库中
$ git add .
说明: 除了能够判断出当前目录(包括其子目录)所有被修改或者已删除的文档,
还能判断用户所添加的新文档,并将其信息追加到索引中
当你正在做一项复杂的工作时,发现了一个和当前工作不相关但是又很讨厌的bug 你这时想先修复bug再做手头的工作,那么就可以用 git stash来保存当前的工作状态,等你修复完bug后执行git stash apply就可以回到之前的工作状态。
保存当前的工作状态
$ git stash
进行 fix bug
fix something
提交此次 fix
$ git commit -am "msg"
回到之前的工作状态
$ git stash apply
标签可以针对某一时间点的版本做标记,常用于版本发布
打标签
$ git tag v1-light # 创建轻量标签 $ git tag -a v1.0 -m "my version 1.0" # 创建附注标签[-a(annotated)] $ git tag -a v1.1 -m "my version 1.1" # 创建附注标签[-a(annotated)] $ git tag -a v2.0 -m "my version 2.0" # 创建附注标签[-a(annotated)]
创建轻量标签不需要传递参数,直接指定标签名称即可,轻量级tag不是对象,它就是个指向特定提交对象的引用
创建附注标签时,参数a即annotated的缩写,指定标签类型,后附标签名。参数m指定标签说明,说明信息会保存在标签对象中。
列出标签
$ git tag # 在控制台打印出当前仓库的所有标签 $ git tag -l 'v1.*' # 搜索符合模式的标签
切换到标签
$ git checkout tagname
查看标签信息
$ git show v1.0
删除标签
$ git tag -d v1.0
给指定的commit打标签
$ git tag -a v1.0 9fbc3d0
标签发布
通常的git push不会将标签对象提交到git服务器,我们需要进行显式的操作
$ git push origin v2 # 将`v0.1.2`标签提交到`git`服务器 $ git push origin –tags # 将本地所有标签一次性提交到`git`服务器
$ git archive --format zip -o filename.zip HEAD
查看指定版本的文件
$ git show SHA-1
查看指定版本的某个文件
$ git show SHA-1:filename
查看指定tag的文件
$ git show tagname
查看分支
$ git branch
建立分支
$ git branch new_branch
或
$ git checkout -b new_branch # 创建分支并切换进去
切换分支
$ git checkout another_branch
合并分支
$ git merge branch_name
删除分支
$ git branch -d existBranch # 删除已经合并好的分支 $ git branch -D existBranch # 删除分支不管是否合并好
修改分支名
$ git branch -m oldname newname
合并多个小版本
$ git rebase -i 分支名(基于哪个分支) 把从第二个pick开始都改成s
更多参考:git-community-book-cn(p50)
$ git reset --hard HEAD # 撤销当前的所有修改,HEAD始终指向最新的 commit 对象 $ git checkout filename # 撤销某个文件里的修改 $ git reset --hard HEAD^ # 撤销上次提交,"不可逆转" $ git checkout SHA-1 # 回到之前的某个版本 $ git checkout master # 回到最新版本
修复提交
$ git reset --soft HEAD^ # 将修改保存到暂存区,可以用`git diff --staged`查看 $ git commit -a -c ORIG_HEAD# 用刚才的HEAD的提交信息来提交
重置多个提交多次修改
$ git reset --mixed SHA-1 # SHA-1是要合并版本的前一个版本的值 $ git add -p # 将不相关的功能分开 $ git commit -m "msg1" $ git add -p $ git commit -m "msg2" $ git checkout master $ git merge xxx
修改最后一次的提交信息
$ git commit --amend $ git reset [--(mixed|soft|hard)] SHA-1
查看文件的每个部分是谁修改的
$ git blame filename $ git blame -L 2,+5 filename # 查找从第二开始的五行是谁修改的
TODO:全局忽略
一般某个项目开发过程中都会产生一些中间文件,这些文件是我们不想要追踪的。git中可以使用.gitignore文件来忽略这些文件。
在需要的目录下面添加.gitignore文件,其中每一行表示需要忽略的文件的正则表达式。
示例:
.*.swp a.out *~ *.[oa] # 忽略`.o`或`.a`结尾的文件 !libsqlite3.a # 但`libsqlite3.a`除外 /var # 忽略根目录下的 var 目录 bin/ # 忽略`bin/`目录及目录下的所有文件 doc/*.txt # 忽略`doc/`目录下以.txt结尾的文件,但不递归
blob 用来存储文件内容,通常是一个文件
$ find .git/objects -type f # 查看所有更改的 SHA1 $ git hash-object filename # 计算该文件的 hash 值, 此时查看`.git/objects/`可以看到有一个以该哈希值前两个字符相同的文件, 查看这个文件的内容,其内容是剩下的38个字符 $ git show SHA1 # 显示文件的内容 或 $ git cat-file -p SHA1
tree 有点像一个目录,它管理一些 tree 或是 blob(就像文件和子目录)
commit 表示修改历史,描述一个个 tree 之间如何联系起来
tag 标签(轻量级tag不是对象,附注tag是一个对象,它可以指向 blob, tree和commit,大部分时候是commit)
对象之间的关系(TODO)
$ git log $ git cat-file -t SHA1 # 查看对象的类型 $ git cat-file commit dcb300a29 $ git show -s --pretty=raw SHA1 $ git ls-tree dcb300a29 $ git cat-file -t 0016606 $ git cat-file blob 0016606
一个commit对象唯一的指向一个tree对象
每次提交版本都会生成对应的SHA1值,在git中,会对提交(commit)、文件(blob)、目录(tree)、标签(tag)生成一个唯一的SHA1值,
git就是基于此来得知文件或目录的改动,因为这四类对象计算得到的SHA1值都是唯一的,同时你也可以直接使用SHA1值来指代相应的对象。
$ git clone git@github.com:ButBueatiful/test.git test_local
输入你在远程主机的用户名和密码,就可以将项目源代码取回到本地。
注意:
通过git clone获取的远端git库,只包含了远端git库的当前工作分支。如果想获取其它分支信息,需要使用 git branch –r 来查看
如果需要将远程的其它分支代码也获取过来,可以使用命令git checkout -b 本地分支名 远程分支名,其中,远程分支名为git branch –r所列出的分支名, 一般是诸如origin/分支名的样子。如果本地分支名已经存在, 则不需要-b参数。
将本地分支保存到远程(origin是远程代码库名)
$ git push origin new
删除远程分支
$ git push origin :new # 将远端的`new`分支清空,也就是删除它
更新本地仓库
$ git pull # 从远程获取最新版本并merge到本地 $ git fetch # 从远程获取最新版本到本地, 不会自动`merge`,在手动`merge`之前可先`diff`一下差异,比较安全
向远程主机提交代码
查看目前本地仓库的状态
$ git status
添加需要更改的代码到仓库
$ git add changed_files $ git commit -m "更改的内容"
如果添加或删除的代码都需要提交,则可以使用
$ git commit -am "更改的内容"
注意: 提交时请务必填写更新信息,以便于回溯。
首先初始化新的本地仓库
$ mkdir test $ cd test $ git init $ touch README
将文件添加到你的本地git仓库中
$ git add README $ git commit -m 'first commit'
把你在github上仓库的地址添加进去,注意在远程仓库里必须有该地址
$ git remote add origin 'git@github.com:ButBueatiful/test.git'
提交到github上的远程仓库中:
$ git push -u origin master
如果本地已有git仓库, 请遵循以下操作
$ cd existing_git_repo $ git remote add origin 'git@github.com:ButBueatiful/test.git' $ git push -u origin master
列出已暂存的文件
$ git ls-files $ git checkout -f HEAD # 找回删除的文件
合并多个提交
$ git reset --soft # 开始那个提交的SHA-1 $ git reset --soft HEAD~n (n代表要提交的版本个数加一) $ git commit --amend
查看文件的对应行是谁修改的
$ git blame filename
从服务器上clone代码到本机
在本机上创建分支
在本机创建的分支上修改、提交代码
把本机上自己创建的分支合并到主分支上
新建一个分支,把服务器上最新版的代码fetch下来,然后跟自己的主分支合并
生成补丁,把补丁发送给主开发者
解决办法
echo 'unset SSH_ASKPASS' >> ~/.bashrc && source ~/.bashrc