码迷,mamicode.com
首页 > 其他好文 > 详细

Git权威指南(笔记)

时间:2014-12-18 09:18:18      阅读:313      评论:0      收藏:0      [点我收藏+]

标签:chromium   git   path   分支合并   branch   

Git权威指南

跳转至: 导航 搜索

目录

初识Git

  1. git add -u/-A/-p
  2. git pull remote-mirror local-master
  3. 导出提交历史(即从一现有代码生成补丁):
    1. 初始化git版本库。。。(这一步其实可能 很消耗时间,如果代码量很大的话)
    2. git tag v1
    3. git commit -a
    4. git format-patch v1..HEAD 这要求每次提交都是一个修正,实际中可能更想把所有提交合并成一个补丁。。。
  4. 重写提交说明:git commit --amend(修补提交,修改上一次提交???)
    1. 要修改历史提交的说明,需先定位:git rebase -i <commit-id>(怀疑这里rebase不是这么用的吧?)
  5. git diff
    1. --word-diff
    2. --cached
  6. 保存和恢复工作进度(push/pop):
    1. git stash(相对于push)
    2. git checkout <new_branch>
    3. ...
    4. git checkout <origin_branch>
    5. git stash pop
  7. 本地Git,与服务器端svn协同:
    1. git svn fetch(这相当于在Git控制的环境中执行svn update?)
    2. git svn rebase
    3. git svn dcommit
  8. Git命令默认分页(less -FRSX)

Git安装

  1. 获取最新版并丢弃本地修改:
    1. git fetch
    2. git clean -fdx
    3. git reset --hard
    4. git tag
    5. git checkout v1.7.4.1
  2. 命令补齐?/etc/bash_completion
  3. 中文支持:git config --global core.quotepath false
    1. Linux上,最好不要使用UTF-8以外的字符集(GBK)
  4. Mac OS X上安装Git:$ brew install git
  5. p40 Cygwin默认使用UTF-8字符集,并巧妙地与Windows字符集进行转换(?)
  6. PuTTY Pageant:提供SSH私钥?
  7. msysGit环境:
    1. $ ls --show-control-chars *.txt(显示中文文件名)
    2. TortoiseGit对中文提交说明的支持有缺陷???扯淡

Git初始化

  1. git grep
  2. git rev-parse --git-dir
  3. git config可以很方便地操作INI文件:
    1. GIT_CONFIG=test.ini git config a.b.c "Hello"
  4. 别名:git config --global alias.ci "commmit -s"

Git暂存区(stage)

  1. 当执行git status(-s是显示stage内容?)时,首先依据.git/index的时间戳等信息判断工作区是否有改动
    1. (依赖于文件时间戳的设计本质上说不是太可靠。。。)
  2. Git-diff比较:
    1. 工作区 vs 暂存区:git diff
    2. 暂存区 vs HEAD:git diff --cached
    3. 工作区 vs HEAD:git diff HEAD
  3. 不要使用git commit -a(绕过stage,直接提交)
  4. 每次修改需重新git add以增加到stage(这个add确实很容易把人搞糊涂!)

Git对象

  1. git cat-file [-t -p ...] <SHA1-40bit-ID>
  2. .git/objects:ID的前2位作为目录名,后38位作为文件名??
  3. .git/refs/heads/下的引用名称称为分支(引用指向某一个提交id!)# p90 Hg同时使用顺序数字和SHA1??
  4. HEAD^代表HEAD的上一次提交
  5. a5~5 相当于 a5^^^^^
  6. a5:path/to/file

Git重置

  1. git reset --hard HEAD^ (暂存区里的修改可能丢失)
  2. git reset --hard 9e8a761
  3. git reflog show master | head -5
  4. git reset --hard master@{2} 切换master回到2次修改之前
  5. 2种reset
    1. git reset [-q] [<commit>] [--] <paths> ...
    2. git reset[--soft / --mixed / --hard / --merge / --keep] [-q] [<commit>]

Git检出

  1. checkout时重置当前HEAD
  2. p102 当不是从master检出并提交后,由于提交没有被分支跟踪,则有可能被从版本库清除
  3. 解救:切换到master,然后merge刚才的提交(开发分支?):
    1. git merge acc2f9
  4. git log --graph --pretty=online
  5. *reset的默认是HEAD,而checkout的默认是stage(index)
  6. 检出并创建新分支:git checkout [-m] [[-b / --orphan] <new_branch>] [<start_point>]

git stash

  1. git stash(保存当前工作进度,分别对stage、working)可以多次保存进度!(save point?)
  2. git-<cmd>:Git大部分命令也是用脚本实现的(!),这一点上与Hg类似
  3. stash内部实现实际上就是一个特殊的分支(refs/stash)而已
    1. 与SVN的trunk/tags/branch目录相比,Git则把这种状态划分内置到命令里去了(话说这样一来我觉得还是SVN更容易理解的说)
    2. 把2个SVN串联起来实际上就相当于Git的stage了,哈哈

Git基本操作

  1. git stash apply(pop的话会删除进度?)
  2. 本地删除不会影响stage,而git rm则会修改stage,下一次commit生效
  3. git add 参数
    1. -u:标记本地所有改动(更新、删除)
    2. -A:所有改动和增加
    3. -i:交互式手工选择
  4. git describe
  5. .gitignore
    1. /TODO 只忽略此目录下的TODO
    2. .svn/ 所有的.svn(子)目录
  6. git archive --format=tar --prefix=1.0/ v1.0 | gzip > foo-v1.0.tag.gz

历史

  1. gitk --all
  2. gitk --since="2 weeks ago" #这种时间描述应该是从Ruby里借鉴来的
  3. gitg & (基于GTK+的)
  4. qgit & (基于Qt的)
  5. git blame -L 6,+5 Readme.txt
  6. git bisect start/good/bad/reset
  7. * Hg只能悔一次,Git因为有强大的reset,可以任意多次
  8. 时间旅行“回到未来”(这个比喻真不恰当!)
    1. git cherry-pick
    2. git rebase --onto <newbase> <since> <until>
    3. git rebase -i
  9. 丢弃历史,仅保留最近的100次提交:
    1. 创建根提交:git cat-file commit A^0 | sed -e ‘/^parent/ d‘ > tmpfile
    2. git hash-object -t commit -w --tmpfile
    3. git rebase --onto <new-root-commit-id> A master
  10. 分布式情况下修正一个错误提交的方法是反转提交:
    1. git revert HEAD

Git克隆

  1. git clone <repos> <new-dir>
    1. 不带参数(非裸版本库,工作区直接push会导致错误?只允许从备份库pull,不能反向push?)
    2. --bare(只有.git/,裸版本库,这时可以push)
    3. --mirror
      1. 可以与上游git fetch同步
  2. git push/pull [<remote-repos> [<ref-specs>]]

Git库管理

  1. git show-ref
    1. refs/heads/开头的是分支
    2. refs/remotes/是远程分支的本地映射分支
    3. refs/tags/是里程碑
  2. *为什么clone远程版本库会产生对象库打包和引用打包的效果呢?(文件在传输时被压缩了。。。)
  3. git fsck
    1. 没有被引用关联的松散对象,如暂存区引入的大文件
    2. git prune
  4. git fsck --no-reflogs
    1. git reflog expire --expire=now --all
    2. git prune
  5. git gc
    1. --prune=now
  6. 1.6.6+ 部分git命令会自动执行git gc --auto
    1. git merge
    2. git receive-pack(当接受到对方的push时)
    3. git rebase -i
    4. git am
  7. 触发条件:.git/objects/17目录下对象超过27个时

Git协议与工作协同

  1. 智能协议 vs 哑协议(.git/info/refs,git/objects/info/packs)
  2. ‘快进式’push:推送的push必须基于版本库的相应分支的现有基础
  3. 强制push(这种情况下会覆盖其他用户的,??)
  4. merge后push:
    1. git pull
    2. git push
  5. 禁止‘快进式’push:
    1. git --git-dir=/path/to/repos/shared.git config receive.denyNonFastForwards true
  6. 通过hooks和授权允许特定用户强制push(。。。)

冲突解决

  1. git pull = fetch + merge
  2. 自动合并
    1. 不同文件
    2. 相同文件的不同行
    3. 文件移动 & 文件内容的修改
  3. 自动合并成功,但有逻辑冲突:测试!!!
  4. 冲突解决:<<<<<<<=======>>>>>>>
    1. kdiff3
  5. 树冲突
  6. 合并策略:git merge [-s <strategy>] [-X <strategy-options>] <commit> ...
    1. ours
    2. theirs
    3. subtree
    4. octopus

Git里程碑

  1. git tag
  2. 命名规范:v1.0-init
    1. 不要以-开头
    2. / .不能出现在最后
    3. 不能出现2个以上连续的.
    4. 不能使用特殊字符: ~ ^: ? \
    5. 不能以.lock结尾

Git分支

  1. master:随着提交而变化
  2. 发布分支(Bugfix)
  3. 特性分支
  4. Vendor分支(专门创建一个与上游同步的分支)
  5. git branch dever-name/feature-name(分支命名带/?)
  6. 合并到主线:
    1. git checkout master
    2. git merge user1/funcA
    3. git cherry
    4. git push
    5. git branch -d user1/funcA
  7. 采用rebase时的分支关系图要比merge简单?

远程版本库

  1. git branch -r
    1. .git/refs/remotes/origin/ #see .git/config
  2. 从远程分支创建跟踪分支:git checkout -b v-1.x origin/v-1.x(如果没有名字冲突,可直接git checkout v-1.x)
    1. 跟踪分支的好处是可以git pull自动维护与上游分支的一致更新
    2. 如果希望对本地分支也支持跟踪功能:--track
  3. 注册新的远程版本库:git remote add new-remote-name <URL-to-remote-repos-git>
  4. git remote update
  5. 远程版本库中的tags同步到本地,不会创建新的名字空间!!
    1. -n(--no-tags)

补丁文件交互

  1. 创建补丁:
    1. git format-patch -s HEAD~3..HEAD(最近的3个提交导出为补丁文件)
  2. 接受邮件:mail -f user1-archive(mbox格式)
  3. 首先切换到本地的基准点:git checkout -b user1-patch-base HEAD~3
  4. 应用补丁:git am user1-archive
    1. 或可:cat *.patch | git am
  5. git apply:应用一般格式的补丁,但不提交
  6. StGit(没看出这里的用处到底怎么样的)
    1. stg uncommit -n 3
    2. stg pop -a(撤销版本库上的提交?)
    3. stg ser
    4. stg push/goto ...
    5. stg refresh
    6. stg show
    7. stg export(quilt格式的?)
  7. Quilt

经典Git协同模型

  1. Hg + MQ
    1. 入栈的补丁转为提交,出栈则是移走最新的提交

Topgit协同模型

  1. master用于与上游同步,建立本地的特性分支(refs/heads/t/feature_name)
  2. 为了实现特性分支导出为补丁,引入了特殊的引用(refs/top-bases/*),用于追踪各特性分支的基准分支
  3. tg create t/new-feature-branch-name [DEPS ...] 可指定多个依赖分支???
    1. 当依赖分支有更新时,tg info t/feature3 可看到t/feature1上的提交
  4. tg update
  5. tg summary
    1. --graphviz | dot -T png -o topgit-layout.png
  6. tg remote [--populate] [REMOTE]
  7. tg export
    1. --collapse
  8. .topdeps:删除重复的依赖??

子模块(submodule)协同模型

  1. svn:externals
  2. git submodule add /path/to/repos/libA.git lib/lib_a
  3. clone时默认不包含submodules,如果需要的话,
    1. git submodule init
    2. git submodule update
  4. ???这里的讲解太含糊了。。。fuck

子树合并*

  1. git read-tree --prefix=lib util-branch
  2. git checkout -- lib
  3. git write-tree
  4. git commit-tree ...
  5. 反方向:将项目的一个子目录导出为新的git项目,要求导出对应的历史。。。
    1. #see git filter-branch
  6. git-subtree插件*

Android式多版本库协同

  1. repo(相当于用Python脚本把多个Git仓库用目录组织起来。。。,manifest.xml)
  2. repo init --mirror -u git://.../manifest.git
    1. repo sync
  3. repo upload:向Gerrit服务器进行git push

Git与SVN协同模型

  1. git svn clone <svn-path> <dir-name>
  2. git svn fetch
  3. git svn rebase(注意,SVN提交都是线性的!)
  4. git rebase --continue
  5. git svn dcommit
    1. 推送之后,Git里的提交说明中嵌入了git-svn-id:标签(把映射关系加到Git commit log中,聪明!)
  6. 注意:使用git-svn时尽量不要在不同分支之间进行合并,而是尽量在一个分支上线性提交
    1. 如果真的需要在SVN不要分支间合并,使用SVN 1.5+,因为这样可以正确记录svn:mergeinfo属性

Git服务器

  1. 只读的HTTP哑协议
  2. 智能HTTP:1.6.6+ git-http-backend
  3. Gitweb:只读访问?
    1. git instaweb(如果安装了)
  4. git-daemon
  5. SSH方式

Gitolite

  1. 又是Perl开发的?
  2. gitolite-admin管理库?(Devops?)
  3. 访问控制及授权:略

Gitosis

  1. Python开发,SKIP

Gerrit代码审核

  1. 最早的Gerrit由Python之父Guido van Rossum开发的Rietveld分支而来,现在的Gerrit是用Java实现的
  2. 特殊引用:
    1. refs/for
      1. 创建一个<review-id>,并建立refs/changes/nn/<review-id>/m
    2. refs/changes
  3. hooks/commit-msg
    1. Change-Id
  4. Gerrit服务器架设:。。。略
    1. 第一个用户为系统管理员;建立公钥以启动ssh服务

Git托管

迁移到Git

  1. cvs2svn > cvs2git
  2. Hg迁移到Git:fast-export(略)

Git的其他应用

  1. etckeeper
  2. 作者自己开发的Gistore,shit
  3. git diff --binary

Git的其他特性

  1. 属性文件?
  2. hooks
    1. applypatch-msg
    2. pre/post-applypatch
    3. pre/post-commit
    4. prepare-commit-msg
    5. commit-msg
    6. pre-rebase
    7. post-checkout/merge
    8. pre/post-receive
    9. update
    10. post-update
    11. pre-auto-gc
    12. post-rewrite
  3. sparse checkout
    1. skip-worktree
  4. 浅clone:
    1. --depth 2
      1. .git/shadow
  5. 提交嫁接:.git/info/grafts
  6. 提交替换:.git/refs/replace/
  7. git notes

附录 

Git权威指南(笔记)

标签:chromium   git   path   分支合并   branch   

原文地址:http://blog.csdn.net/cteng/article/details/41991961

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!