git学习笔记

来源:互联网 发布:户外驴友用哪个软件 编辑:程序博客网 时间:2024/06/05 14:45
Git术语
  1. working directory: 工作区
  2. staging area: 暂存区
  3. git directory/repository: 仓库
  4. remote branch: 远程分支,是对远程仓库中的分支的索引,它们是一些无法移动的本地分支。

Git基础

  1. Git存储
    Git 和其他版本控制系统的主要差别在于,Git 只关心文件数据的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异。这类系统(CVS,Subversion,Perforce,Bazaar 等等)每次记录有哪些文件作了更新,以及都更新了哪些行的什么内容。Git 保存的不是文件差异或者变化量,而只是一系列文件快照。
  2. 文件的3种状态
    对于任何一个文件,在 Git 内都只有三种状态:已提交(committed),已修改(modified)和已暂存(staged)。已提交表示该文件已经被安全地保存在本地仓库中了;已修改表示修改了某个文件,但还没有提交保存;已暂存表示把已修改的文件放在下次提交时要保存的清单中。
    由此我们看到 Git 管理项目时,文件流转的三个工作区域:Git 的工作目录,暂存区域,以及本地仓库。
    《Pro <wbr>Git》学习笔记
    图 1-6. 工作目录,暂存区域,以及本地仓库
    所谓的暂存区域只不过是个简单的文件,一般都放在 Git 目录中。有时候人们会把这个文件叫做索引文件,不过标准说法还是叫暂存区域。
    基本的 Git 工作流程如下:
    1. 在工作目录中修改某些文件。
    2. 对修改后的文件进行快照,然后保存到暂存区域。
    3. 提交更新,将保存在暂存区域的文件快照永久转储到 Git 目录中。
    工作目录下面的所有文件都不外乎这两种状态:已跟踪或未跟踪。已跟踪的文件是指本来就被纳入版本控制管理的文件,在上次快照中有它们的记录,工作一段时间后,它们的状态可能是未更新,已修改或者已放入暂存区。而所有其他文件都属于未跟踪文件。它们既没有上次更新时的快照,也不在当前的暂存区域。初次克隆某个仓库时,工作目录中的所有文件都属于已跟踪文件,且状态为未修改。
    《Pro <wbr>Git》学习笔记
  3. 配置文件
    • /etc/gitconfig 文件:系统中对所有用户都普遍适用的配置。若使用 git config 时用 --system选项,读写的就是这个文件。
    • ~/.gitconfig 文件:用户目录下的配置文件只适用于该用户。若使用 git config 时用 --global选项,读写的就是这个文件。
    • 当前项目的 git 目录中的配置文件(也就是工作目录中的 .git/config 文件):这里的配置仅仅针对当前项目有效。每一个级别的配置都会覆盖上层的相同配置,所以 .git/config 里的配置会覆盖/etc/gitconfig 中的同名变量。
  4. 配置文件-忽略某些文件(.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
  5. 分支(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.email cai8311@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可选值还有shortfull 和 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在远程分支serverfix的基础上分化出一个新的分支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: 删除远程分支serverfix
    git 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 clone git://github.com/schacon/grit.git
    git clone git://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 fileName
    git 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 tag
    git 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=oneline 
    9fceb02d0ae598e95dc970b74767f19372d61af8 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移除储藏
0 0
原创粉丝点击