git学习笔记
来源:互联网 发布:户外驴友用哪个软件 编辑:程序博客网 时间:2024/06/05 14:45
- working directory: 工作区
- staging area: 暂存区
- git directory/repository: 仓库
- remote branch:
远程分支,是对远程仓库中的分支的索引,它们是一些无法移动的本地分支。
Git基础
- Git存储
Git 和其他版本控制系统的主要差别在于,Git 只关心文件数据的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异。这类系统(CVS,Subversion,Perforce,Bazaar 等等)每次记录有哪些文件作了更新,以及都更新了哪些行的什么内容。Git 保存的不是文件差异或者变化量,而只是一系列文件快照。 - 文件的3种状态
对于任何一个文件,在 Git 内都只有三种状态:已提交(committed),已修改(modified)和已暂存(staged)。已提交表示该文件已经被安全地保存在本地仓库中了;已修改表示修改了某个文件,但还没有提交保存;已暂存表示把已修改的文件放在下次提交时要保存的清单中。
由此我们看到 Git 管理项目时,文件流转的三个工作区域:Git 的工作目录,暂存区域,以及本地仓库。
图 1-6. 工作目录,暂存区域,以及本地仓库
所谓的暂存区域只不过是个简单的文件,一般都放在 Git 目录中。有时候人们会把这个文件叫做索引文件,不过标准说法还是叫暂存区域。
基本的 Git 工作流程如下:- 在工作目录中修改某些文件。
- 对修改后的文件进行快照,然后保存到暂存区域。
- 提交更新,将保存在暂存区域的文件快照永久转储到 Git 目录中。
- 配置文件
/etc/gitconfig
文件:系统中对所有用户都普遍适用的配置。若使用 git config
时用 --system
选项,读写的就是这个文件。~/.gitconfig
文件:用户目录下的配置文件只适用于该用户。若使用 git config
时用 --global
选项,读写的就是这个文件。- 当前项目的 git 目录中的配置文件(也就是工作目录中的
.git/config
文件):这里的配置仅仅针对当前项目有效。每一个级别的配置都会覆盖上层的相同配置,所以 .git/config
里的配置会覆盖 /etc/gitconfig
中的同名变量。
- 配置文件-忽略某些文件(.gitignore)
工作目录及其子目录下每个目录都可以维护一个.gitignore文件,用于将某些文件排除在版本控制外,如eclipse项目的.project文件- 所有空行或者以注释符号
#
开头的行都会被 Git 忽略。 - 可以使用标准的 glob 模式匹配。
- 匹配模式最后跟反斜杠(
/
)说明要忽略的是目录。 - 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(
!
)取反。
所谓的 glob 模式是指 shell 所使用的简化了的正则表达式。星号(
*
)匹配零个或多个任意字符;[abc]
匹配任何一个列在方括号中的字符(这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个 c);问号(?
)只匹配一个任意字符;如果在方括号中使用短划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配(比如[0-9]
表示匹配所有 0 到 9 的数字)。 我们再看一个
.gitignore
文件的例子: # 此为注释 – 将被 Git 忽略
# 忽略所有 .a 结尾的文件
*.a
# 但 lib.a 除外
!lib.a
# 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
/TODO
# 忽略 build/ 目录下的所有文件
build/
# 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt
doc/*.txt
- 所有空行或者以注释符号
- 分支(branch)
在很多版本控制系统中,这是个昂贵的过程,常常需要创建一个源代码目录的完整副本,对大型项目来说会花费很长时间。和许多其他版本控制系统不同,Git 鼓励在工作流程中频繁使用分支与合并,哪怕一天之内进行许多次都没有关系。
工作区保存着一个名为 HEAD 的特别指针,它是一个指向你正在工作中的本地分支的指针(可以将 HEAD 想象为当前分支的别名。)。
使用git branch命令不仅可以查看所有分支列表,还可以看到分支名前带有*就是当前分支,当然使用git status也可以做到。
master是Git中默认创建的一个分支
远程分支(remote branch)是对远程仓库中的分支的索引。它们是一些无法移动的本地分支;只有在 Git 进行网络交互时才会更新。
远程分支就像是书签,提醒着你上次连接远程仓库时上面各分支的位置。我们用(远程仓库名)/(分支名)
这样的形式表示远程分支。 从远程分支 checkout
出来的本地分支,称为 跟踪分支(tracking branch)。跟踪分支是一种和某个远程分支有直接联系的本地分支。在跟踪分支里输入 git push
,Git 会自行推断应该向哪个服务器的哪个分支推送数据。同样,在这些分支里运行git pull
会获取所有远程索引,并把它们的数据都合并到本地分支中来。
在克隆仓库时,Git 通常会自动创建一个名为master
的分支来跟踪 origin/master
。这正是git push
和git pull
一开始就能正常工作的原因。
Git工作流(workflow)
Git常用命令
- git help
查询子命令或子命令帮助信息
git help:列出所有子命令
git help config:列出config子命令的帮助信息 - git config
管理配置信息
git config --system user.name "Brody Cai"
git config --global user.emailcai8311@gmail.com
git config --list
git config user.name
git help config - git add
这是个多功能命令,根据目标文件的状态不同,此命令的效果也不同:可以用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等 - git status
该命令仅仅列出了修改过的文件(包括已暂存和未暂存的更新),如果要查看具体修改了什么地方,可以用git diff
命令 - git diff
git diff:此命令比较的是工作目录中当前文件和暂存区域快照之间的差异,也就是修改之后还没有暂存起来的变化内容
git diff --staged(或git diff --cached):此命令比较的是已暂存起来的文件和上次提交时的快照之间的差异
请注意,单单git diff
不过是显示还没有暂存起来的改动,而不是这次工作和上次提交之间的差异。所以有时候你一下子暂存了所有更新过的文件后,运行 git diff
后却什么也没有,就是这个原因。 - git commit
git commit -m "your commit comments":提交时记录的是放在暂存区域的快照,任何还未暂存的仍然保持已修改状态。也就是说只有暂存区的变更(staged)会被提交,工作区的变更(modified)不提交
git commit -a -m "commit all": 跳过暂存区自动把所有已经跟踪过的文件暂存起来一并提交。-a参数会把暂存区和工作区的变更一并提交,相当于在工作区自动执行了git add命令。需要注意的是“已经跟踪过的文件”意思是指新建的文件从未被add到暂存区的文件不会自动提交。 - git rm
移除文件
git rm readme.txt:将暂存区的指定文件删除,同时删除对应的工作区文件。最后提交的时候,该文件就不再纳入版本管理了。如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f
(译注:即 force 的首字母),以防误删除文件后丢失修改的内容。
git rm --cached readme.txt:把指定文件从 Git 仓库中删除(亦即从暂存区域移除),但指定文件保留在当前工作目录中。如:不小心把eclipse的.project文件提交到了Git仓库中,使用该命令即可将.project从仓库中移除,同时工作区的.project仍保留 - git mv
移动/重命名工作区和暂存区文件
git mv file_from file_to - git log
查看提交历史git log -p -2:
-p
选项展开显示每次提交的内容差异,用 -2
则仅显示最近的两次更新
git log --stat:仅显示简要的增改行数统计
git log --pretty=oneline:将每个提交放在一行显示,这在提交数很大时非常有用。pretty可选值还有 short
,full
和 fuller
git log --pretty=format:"%h - %an, %ar : %s":
定制要显示的记录格式,这样的输出便于后期编程提取分析
如下列出了常用的格式占位符写法及其代表的意义。选项 说明 %H 提交对象(commit)的完整哈希字串 %h 提交对象的简短哈希字串 %T 树对象(tree)的完整哈希字串 %t 树对象的简短哈希字串 %P 父对象(parent)的完整哈希字串 %p 父对象的简短哈希字串 %an 作者(author)的名字 � 作者的电子邮件地址 � 作者修订日期(可以用 -date= 选项定制格式) %ar 作者修订日期,按多久以前的方式显示 %cn 提交者(committer)的名字 � 提交者的电子邮件地址 � 提交日期 %cr 提交日期,按多久以前的方式显示 %s 提交说明
git log --pretty=format:"%h %s" --graph: 用ASCII 字符串表示的简单图形,形象地展示了每个提交所在的分支及其分化衍合情况
下表列出了git log一些其他常用的选项及其释义
选项 说明 -p 按补丁格式显示每个更新之间的差异。 --stat 显示每次更新的文件修改统计信息。 --shortstat 只显示 --stat 中最后的行数修改添加移除统计。 --name-only 仅在提交信息后显示已修改的文件清单。 --name-status 显示新增、修改、删除的文件清单。 --abbrev-commit 仅显示 SHA-1 的前几个字符,而非所有的 40 个字符。 --relative-date 使用较短的相对时间显示(比如,“2 weeks ago”)。 --graph 显示 ASCII 图形表示的分支合并历史。 --pretty 使用其他格式显示历史提交信息。可用的选项包括 oneline,short,full,fuller 和 format(后跟指定格式)。 -(n) 仅显示最近的 n 条提交 --since, --after 仅显示指定时间之后的提交。 --until, --before 仅显示指定时间之前的提交。 --author 仅显示指定作者相关的提交。 --committer 仅显示指定提交者相关的提交。
- git branch
git branch:
git branch -v:
git branch -r: 查看远程分支
git branch --merged:
git branch --no-merged: git branch -d
git branch -D。
git branch iss53: 创建一个分支,命名为iss53
git checkout -b iss53: 创建一个分支,命名为iss53,并checkout该分支
此命令相当于执行了如下两个命令:
git branch iss53
git checkout iss53
git checkout -b serverfix origin/serverfix:
git checkout --track origin/serverfix: 效果同上,使用远程分支的名字作为本地分支名
git branch -d branch1: 删除branch1这个分支
- git merge
git checkout master
git merge iss53
checkout master分支,将iss53这个分支merge到master。如遇到冲突,需要手动修改冲突文件,修改后使用git add命令标记为已解决,之后就可以commit提交了
git merge origin/serverfix:把origin仓库中的远程分支serverfix的内容合并到当前分支 - git push
git push origin serverfix:取出我在本地的 serverfix 分支,推送到远程仓库的 serverfix 分支中去。与git push origin serverfix:serverfix效果等同
git push origin :serverfix: 删除远程分支serverfixgit push [远程名] [本地分支]:[远程分支]
,如果省略 [本地分支]
,那就等于是在说“在这里提取空白然后把它变成[远程分支]
”。
git push origin master --force忽略origin repository与本地的版本差异,强制push覆盖 - git rebase
衍合,把在一个分支里提交的改变移到另一个分支里重放一遍
git checkout experiment
git rebase master
它的原理是回到两个分支最近的共同祖先,根据当前分支(也就是要进行衍合的分支experiment
)后续的历次提交对象,生成一系列文件补丁,然后以基底分支(也就是主干分支master
)最后一个提交对象为新的出发点,逐个应用之前准备好的补丁文件,最后会生成一个新的合并提交对象,从而改写experiment
的提交历史,使它成为 master
分支的直接下游
git rebase --onto master server client
取出client
分支,找出 client
分支和 server
分支的共同祖先之后的变化,然后把它们在 master
上重演一遍。 现在可以快进(fast forward) master
分支了: git checkout mastergit merge client
衍和的原则:一旦分支中的提交对象发布到公共仓库,就千万不要对该分支进行衍合操作。
Git FAQ
创建新Git项目
- 将已存在项目转换为Git项目
cd existing-project
git init
git add --all
git commit -m"first commit"
git remote add origin http://your_host/your_git_path/your_project.git
git push origin master
- 将本地Git项目推送到远程仓库
cd existing-git-project
git remote add origin http://your_host/your_git_path/your_project.git
git push origin master
显然,除了origin我们可以维护多个远端仓库,取名和地址不同就可以了
- 将已存在项目转换为Git项目
克隆项目
git clone git://github.com/schacon/grit.git
git clonegit://github.com/schacon/grit.git mygritgit
git clone类似与svn checkout,clone形象地表达了Git分布式的特性。上面两个命令的区别是第一个默认创建一个grit目录作为本地仓库,第二个命令手动指定了目录名为mygrit。
Git默认使用origin这个名字来标识你所克隆的原始仓库。默认情况下 git clone
命令本质上就是自动创建了本地的 master 分支用于跟踪远程仓库中的 master 分支(假设远程仓库确实有 master 分支) 清除版本库信息(即脱离Git版本库控制)
一般都是用来将原有项目托管到新版本库时才会用到
cd
your_git_project git rm
--cached -r ./ rm
-r .git 如何撤销
修改最后一次提交
有时候我们提交完了才发现漏掉了几个文件没有加,或者提交信息写错了。想要撤消刚才的提交操作,可以使用
--amend
选项重新提交: $ git commit --amend
此命令将使用当前的暂存区域快照提交。如果刚才提交完没有作任何改动,直接运行此命令的话,相当于有机会重新编辑提交说明,但将要提交的文件快照和之前的一样。
启动文本编辑器后,会看到上次提交时的说明,编辑它确认没问题后保存退出,就会使用新的提交说明覆盖刚才失误的提交。
如果刚才提交时忘了暂存某些修改,可以先补上暂存操作,然后再运行
--amend
提交: $ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend上面的三条命令最终只是产生一个提交,第二个提交命令修正了第一个的提交内容。
取消已经暂存的文件
git reset HEAD ...: 回归到之前已修改未暂存的状态取消对未暂存文件的修改
git checkout -- ...:回归到之前未修改的状态 删除未跟踪(untracked)文件
untracked,即从未add到过暂存区的文件git clean -nd测试删除(dry run) git clean -fd真实删除 当然也可以使用linux rm命令删除将一个文件从历史提交中恢复
git checkout CommitId fileNamegit commit -m "revert a file modification"远程仓库的使用
查看当前的远程库
git remote:只显示远程仓库简称 git remote -v:显示远程仓库简称和对应的克隆地址 添加远程仓库
git remote add [shortname] [url]
demo:
git remote add pb git://github.com/paulboone/ticgit.git 从远程仓库抓取数据
git fetch [remote-name]此命令会到远程仓库中拉取所有你本地仓库中还没有的数据(从你上次clone以来别人上传到此远程仓库中的所有更新或是上次 fetch 以来别人提交的更新)。fetch 命令只是将远端的数据拉到本地仓库,并不自动合并到当前工作分支,只有当你确实准备好了,才能手工合并。demo:git fetch origin 推送数据到远程仓库
git push [remote-name] [branch-name]只有在所克隆的服务器上有写权限,或者同一时刻没有其他人在推数据,这条命令才会如期完成任务。如果在你推数据前,已经有其他人推送了若干更新,那你的推送操作就会被驳回。你必须先把他们的更新抓取到本地,合并到自己的项目中,然后才可以再次推送。查看远程仓库信息
git remote show [remote-name]远程仓库的删除和重命名
git remote rm[remote-name] git remote rename[old-remote-name] [new-remote-name] 打标签(tag)
列显已有的标签
git taggit tag -l 'v1.4.2.*'新建标签
Git 使用的标签有两种类型:轻量级的(lightweight)和含附注的(annotated)。轻量级标签就像是个不会变化的分支,实际上它就是个指向特定提交对象的引用。而含附注标签,实际上是存储在仓库中的一个独立对象,它有自身的校验和信息,包含着标签的名字,电子邮件地址和日期,以及标签说明,标签本身也允许使用 GNU Privacy Guard (GPG) 来签署或验证。含附注的标签:git tag -a v1.4 -m 'my version 1.4'轻量级的标签:git tag v1.4-lw查看标签信息:git show v1.4-lw后期加注标签
我们忘了在提交 “updated rakefile” 后为此项目打上版本号 v1.2,没关系,现在也能做。只要在打标签的时候跟上对应提交对象的校验和(或前几位字符)即可$ git log --pretty=oneline9fceb02d0ae598e95dc970b74767f19372d61af8 updated rakefile 964f16d36dfccde844893cac5b347e7b3d44abbc commit the todo 8a5cbc430f1a9c3d00faaeffd07798508422908a updated readme $ git tag -a v1.2 9fceb02分享标签
默认情况下,git push
并不会把标签传送到远端服务器上,只有通过显式命令才能分享标签到远端仓库。其命令格式如同推送分支,运行 git push origin [tagname]
即可。 如果要一次推送所有本地新增的标签上去,可以使用git push origin --tags
小技巧
Git命令别名
为常用命令设置别名
$ 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 --global alias.unstage 'reset HEAD --'
这样一来,下面的两条命令完全等同:
$ git unstage fileA
$ git reset HEAD fileA
查看最后一次提交信息
$ git config --global alias.last 'log -1 HEAD'
然后要看最后一次的提交信息,就变得简单多了:
$ git last
取消储藏(Un-applying a Stash)
git config --global alias.stash-unapply '!git stash show -p | git apply -R'
Git坑
在windows下的文件的权限因为无法和linux上完全一致,所以用Git检出的文件权限可能显示为被更改。另外因为windows下的换行和linux上也不一样,协作开发时也容易出问题。所以在windows上使用Git的同学需要加上以下2行配置参数:git config --global core.filemode
false
git config --global core.autocrlf
true
第一句是忽略文件权限的改动。
第二句是将文件checkout时自动把LF转成CRLF,check in 时自动把CRLF转成LF
临时性储藏你的工作
经常有这样的事情发生,当你正在进行项目中某一部分的工作,里面的东西处于一个比较杂乱的状态,而你想转到其他分支上进行一些工作。问题是,你不想提交进行了一半的工作,否则以后你无法回到这个工作点。解决这个问题的办法就是git stash
命令。
git stash: 储藏当前工作区
git stash list:查看现有的储藏
git stash apply: 应用最近的储藏到工作区
git stash apply stash@{2}: 将stash@{2}这个储藏应用到工作区
对文件的变更被重新应用,但是被暂存的文件没有重新被暂存。想那样的话,你必须在运行git stash apply
命令时带上一个 --index
的选项来告诉命令重新应用被暂存的变更。 git stash pop:
重新应用储藏,同时立刻将其从堆栈中移走
git stash drop:移除储藏
- 【git】git学习笔记
- Git学习笔记-Git Branching
- Git学习笔记:Git命令
- git常用命令-Git学习笔记
- Git学习笔记--Git入门
- Git 学习笔记 --- 自定义Git
- git/github学习笔记
- git 学习笔记
- Git 学习笔记
- git学习笔记
- git 学习笔记
- Git学习笔记 - 1
- Git学习笔记
- Git学习笔记 - 1
- git/github学习笔记
- git学习笔记
- Git 学习笔记
- GIT之学习笔记
- svn 分支的创建及合并
- mac 下 sublime text 2 主要快捷键列表
- HDU 1026(bfs)
- 转载:GreenPlum的并行查询优化策略
- CSS禁止选择文本功能(兼容IE,火狐等浏览器)
- git学习笔记
- poj2486解题报告
- HDU 1032(水题)
- USB Phy/ULPI (2-读写USB Phy寄存器)
- 随便写了个堆排序程序
- iOS 第三方控件GIFView的学习记录
- 学习grep命令时候遇到的问题
- C++中cin、cin.get()、cin.getline()、getline()、gets()等函数的用法
- HDU 1039(水题)