Git


Git 的内部结构

Git 真正是一个面向程序员的工具,它的内部数据结构是一个有向无环图,并且,你必须理解它的内部数据结构后,才能掌握它。因为你的很多操作,都其实对应的是这个有向无环图的操作。比如:


git commit 就是增加一个结点。

git commit –amend 就是改发一个结点。

git reset 就是修改 HEAD 指向的结点。

另外,Git 内部包括三个区域:工作区,暂存区和版本库。

git add 是将工作区的内容保存到暂存区

git checkout 是将暂存区的内容覆盖工作区

git commit 是将暂存区的内容保存到版本库

git reset 默认情况下是将版本库的内容覆盖工作区

git reset --hard 将所有更改全部撤销

git diff 也有三种情况,分别是比较工作区与暂存区,工作区与版本库,暂存区与版本库之间的差别


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

svn 的 svn revert filename 对应的其实是 git checkout -- filename, 而 git revert xxx 是基于 xxx 提交所做的改动,做一次反向提交,和 svn revert 完全不一样。


节省Clone体积

有些时候,我们只想简单学习一下项目代码,这个时候,用 git clone rep_address --depth 1可以只 clone 每个文件最新的一个提交,这样速度会快很多。

强制推送

一旦推送到远程仓库后,就不要用类似 git reset, git ci --amend, git rebase 等破坏性提交了,否则远程仓库会因为你的新推送不是 Fast Forward 而拒绝提交。如果实在不小心做了。在确定别人没有检出前,用 git push -f 可以强制推送到远程仓库中。


设置常用命令的别名

在用户的 home 目录下,有一个 .gitconfig 文件,里面可以配置一些别名,方便平时的 git 操作。

特别是那些平日使用 SVN 的短命令习惯了的同学,配置一下别名后,使用 git 就会相当顺手了。我配置的别名如下。这里特别多说一句,有些人喜欢将 ci 设置成 commit -a,这样就不用 git add 来把需要提交的文件加入到暂存区了。在《Git 权威指南》中,作者极力反对这样做。因为 Git 本身在提交前有 add 这步,就是为了让提交者能够审视自己的提交文件,以防止错误的提交发生。


[alias]

    st = status -s

    ci = commit

    l = log --oneline --decorate -13

    ll = log --oneline --decorate

    co = checkout

    br = branch

    rb = rebase

    dci = dcommit


删除不在 Git 管理下的文件

如果你需要删除 Git 下没有加入到版本库中的文件,可以使用:


git clean -nd 测试删除

git clean -fd 真实删除


搭建自己的远程仓库

搭建一个 Git 远程仓库相当简单,直接在一台带 SSH 的服务器上用 git init –bare dirname 即可。本地可以用 git remote 命令来设置多个远程分支。另外,第一次提交的时候,因为远程仓库中没有任何分支,需要用如下指令建立 master 分支:


git remote add origin yourname@yourhost.com:~/path/repository_name

git remote add add2 yourname@yourhost.com:~/path/repository_name

git push origin master

git push add2 master

// 如果 git remote add 设置地址写错了,可以用 git remote set-url 更改:

git remote set-url origin yourname@yourhost.com:~/path/repository_name


如何用 Git 将一个文件的历史提交恢复?

上次遇到一个问题,我某次提交改动了很多文件,但是其中有一个是不应该改的。所以我需要把这次提交中关于那个文件的改动撤销。直接用 git checkout 命令可以检出某一个文件的历史版本,然后就可以将对这个文件的改动取消了。如下:


git checkout CommitId fileName 

git ci -m "revert a file modification"


本地工作区还有未提交的内容时,不能 Pull?

可以先用 git stash 将内容暂存,然后再 pull,成功后再 git stash pop 将修改恢复。


提交的邮箱错了?

有些时候,因为同时在 github 和公司内部做提交,所以用 2 个不同的邮箱。如果一个新工程 clone 下来,忘了用 git config 来设置提交用户名和邮箱,就有可能用错误的邮箱作为账号名提交。这个时候,如果你只是错了最近的一次提交而已,可以用如下命令来将最近的一次提交作者名和邮箱修改:


git config user.email your-email@163.com

git config user.name your-name

git commit --amend --reset-author

如果等你发现的时候,已经错了很多提交了。可以用如下命令来一次性修改多个提交的用户名和邮箱:


git filter-branch -f --env-filter "

    GIT_AUTHOR_NAME='Tang Qiao'

    GIT_AUTHOR_EMAIL='tangqiao@fenbi.com'

    GIT_COMMITTER_NAME='Tang Qiao'

    GIT_COMMITTER_EMAIL='tangqiao@fenbi.com'

" HEAD


提交的时候自动去掉源码末尾的空格

源码末尾的空格几乎都是无意义的,应该去掉的。大多数 review 系统,都会将源码末尾的空格标红。所以,我们何不在提交时让 git 自动帮我们去掉这些空格呢?这个可以通过设置 git 的 hook 来实现,具体方法如下:

用 vim 编辑一个名为 pre-commit 的文件:


vim .git/hooks/pre-commit

输入如下代码,保存退出 vim


#!/bin/sh

if git-rev-parse --verify HEAD >/dev/null 2>&1 ; then

   against=HEAD

else

   # Initial commit: diff against an empty tree object

   against=4b825dc642cb6eb9a060e54bf8d69288fbee4904

fi

# Find files with trailing whitespace

for FILE in `exec git diff-index --check --cached $against -- | sed '/^[+-]/d' | sed -E 's/:[0-9]+:.*//' | uniq` ; do

    # Fix them!

    sed -i '' -E 's/[[:space:]]*$//' "$FILE"

    git add "$FILE"

done

增加 pre-commit 的运行权根:


chmod +x .git/hooks/pre-commit


让常用操作自动带颜色

默认的 git diff, status, log 什么的都是不带颜色的,可以用如下命令让它们都带上颜色。另外还有一些有趣的命令,一并列在下面。


git config --global --add user.email "email@163.com"

git config --global --add user.name "your name"

git config --global alias.co checkout

git config --global alias.br branch

git config --global alias.ci commit

git config --global alias.st status -s

git config --global alias.l log --oneline --decorate -12 

git config --global color.diff auto

git config --global color.status auto

git config --global color.branch auto

git config --global merge.tool kdiff3

git config --global meregtool.kdiff3.path "/usr/bin/kdiff3"  

git config --global alias.visual "!gitk"


自动补全 Git 命令

安装 bash-completion: brew install bash-completion

按要求把以下代码增加到 .bash_profile 文件中:


if [ -f `brew --prefix`/etc/bash_completion ]; then

  . `brew --prefix`/etc/bash_completion

fi

下载 bash-completion 对于 Git 的支持


cd /usr/local/etc/bash_completion.d/

sudo curl -O https://raw.github.com/git/git/master/contrib/completion/git-completion.bash


Git rebase pull

git rebase --continue

Git push到多个远程库

git remote add origin git@github.com:looly/hutool.git

git remote add osc git@git.oschina.net:loolly/hutool.git

git add .

git commit -m 'First commit'

git push -u origin master

git push -u osc master

Git submodule

git submodule add https://github.com/xxx

Git submodule的坑

submodule 项目和它的父项目本质上是 2 个独立的 git 仓库。只是父项目存储了它依赖的 submodule 项目的版本号信息而已。如果你的同事更新了 submodule,然后更新了父项目中依赖的版本号。你需要在 git pull 之后,调用 git submodule update 来更新 submodule 信息。

这儿的坑在于,如果你 git pull 之后,忘记了调用 git submodule update,那么你极有可能再次把旧的 submodule 依赖信息提交上去。对于那些习惯使用 git commit -a 的人来说,这种危险会更大一些。所以建议大家:

  • git pull 之后,立即执行 git status, 如果发现 submodule 有修改,立即执行 git submodule update

  • 尽量不要使用 git commit -a, git add 命令存在的意义就是让你对加入暂存区的文件做二次确认,而 git commit -a 相当于跳过了这个确认过程。

更复杂一些,如果你的 submodule 又依赖了 submodule,那么很可能你需要在 git pull 和 git submodule update 之后,再分别到每个 submodule 中再执行一次 git submodule update,这里可以使用 git submodule foreach 命令来实现: git submodule foreach git submodule update


Remove Subversion control for a folder

find . -iname ".svn" -print0 | xargs -0 rm -r

删除一个submodule

  1. 删除 .gitsubmodule中对应submodule的条目
  2. 删除 .git/config 中对应submodule的条目
  3. 执行 git rm --cached {submodule_path}。注意,路径不要加后面的“/”。例如:你的submodule保存在 supports/libs/websocket/ 目录。执行命令为: git rm --cached supports/libs/websocket

或者

  1. git submodule deinit asubmodule
  2. git rm asubmodule

更新submodule的URL

  1. 更新 .gitsubmodule中对应submodule的条目URL
  2. 更新 .git/config 中对应submodule的条目的URL
  3. 执行 git submodule sync

Git Update by yum

yum install http://opensource.wandisco.com/centos/6/git/x86_64/wandisco-git-release-6-1.noarch.rpm
#Install the latest version of Git 2.x:
yum update git
#Verify the version of Git that was installed:
git --version

一些 Git 的资料

Git Magic 很通俗的一本介绍 Git 的书,比较短小精炼。

Pro Git 全面介绍 Git 的书,非常详细。

《Git 权威指南》 中国人写的一本介绍 Git 的书,也非常通俗。我个人主要就是通过这本书来学习 Git 的。

Github 基于 Git 的开源网站。在 Github 的托管的项目相当多,著名的有:rails, jquery, node, homebrew, three20, jekyll, jquery-ui, backbone, coffee-script, tornado, redis, underscore, asi-http-request, django。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容