http://blog.chinaunix.net/uid-26495963-id-3474178.html

相关知识

gnu interactive tools

一句话概括git: Git is at its heart very stupid simple!

SHA-1哈希值:40个十六进制字符(0-9 及 a-f),它唯一确定一个文件

SCM:soucre control management

安装

Ubuntu

  1. $ sudo apt-get install git-core tig

CentOS

  1. $ sudo yum install git-core

配置

(/etc/gitconfig、~/.gitconfig、.git/config)

类UNIX下软件的配置方式基本上都有两种:用命令、修改配置文件

以下是以本地用户基于命令的配置方式如果想学git这种最原始的方式还是需要掌握的,
当然了你也可以直接修改配置文件来达到相同的效果。

用户信息

  1. $ git config --global user.name "username"
  2. $ git config --global user.email username@mail.com

文本编辑器

  1. $ git config --global core.editor vim

差异分析工具

  1. $ git config --global merge.tool meld

命令别名

  1. $ git config --global alias.co checkout # `co`将会成为`checkout`的别名

查看配置信息

  1. $ git config --list # 查看所有配置信息
  2. $ git config user.name # 查看用户名配置信息
  3. $ cat ~/.gitconfig # 查看配置文件内容

git使用初步

将当前目录初始化为git仓库

  1. $ git init

追踪一个新文件,并加入暂存区

  1. $ git add filename

将当前所有的改动加入到暂存区

  1. $ git add .

提交版本

  1. $ git commit -m "msg"

查看当前仓库状态

  1. $ git status

查看日志

  1. $ git log
  2. $ git log -p -2 # 查看最近两次提交并显示修改内容

创建分支

  1. $ git branch branch_name

切换分支

  1. $ git checkout branch_name

小技巧: 以上两步可以合并成一步

  1. $ git checkout -b branch_name # 创建分支并进入新建的分支

合并分支

  1. $ git merge branch_name

删除分支

  1. $ git branch -d branch_name

git的工作原理

文件的三种状态

对于任何一个文件,在Git内都只有三种状态:

  1. 已提交(committed):表示该文件已经被安全地保存在本地数据库中了

  2. 已修改(modified):表示修改了某个文件,但还没有提交保存

  3. 已暂存(staged):表示把已修改的文件放在下次提交时要保存的清单中

基本的 Git 工作流程如下

  1. 在工作目录中修改某些文件

  2. 对修改后的文件进行快照,然后保存到暂存区域

  3. 提交更新,将保存在暂存区域的文件快照永久转储到Git目录中

通过文件所处的位置来判断状态

  1. 如果是Git目录中保存着的特定版本文件,就属于已提交状态

  2. 如果作了修改并已放入暂存区域,就属于已暂存状态

  3. 如果自上次取出后,作了修改但还没有放到暂存区域,就是已修改状态

文件状态的变化周期

  1. 未跟踪

  2. 跟踪

Git命令详解

git diff

查看尚未暂存的更改与暂存区内容的差异(不会被提交)

  1. $ git diff [filename]

查看已经暂存起来的文件和上次提交的版本之间的差异(下次提交的内容)

  1. $ git diff --staged(或cached) [filename]

查看工作目录与上次提交时之间的所有差别

  1. $ git diff HEAD

查看某两个版本之间的差异

  1. $ git diff ffd98[:filename] b8e7b0[:filename]

git log

这个命令就不多做讲解了,试试各个命令的显示效果,选一个自己喜欢的即可

  1. $ git log
  2. $ git log -2
  3. $ git log -p
  4. $ git log -p -2
  5. $ git log git log -p --author="butbueatiful"
  6. $ git log --pretty=oneline
  7. $ git log --graph
  8. $ git log --pretty=format:'%h : %s' --graph
  9. $ git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative

git commit

  1. $ git commit -m "提交的描述信息"

注意: 如果我们这里不用-m参数的话,Git将调到一个文本编译器(默认是nano)来让你输入提交的描述信息,如果按照我们之前的设置应该是vim。

另外 在.bashrc中加入export EDITOR="vim"也可以达到这种效果,区别在于使用这种方式所有软件的默认编辑器都会变成vim,当然软件自己的配置优先级更高。

  1. $ git commit -a -m "提交的描述信息"

  2. $ git commit -am "提交的描述信息"

说明: -a选项可只将所有被修改或者已删除的且已经被Git追踪的文档提交倒仓库中

  1. $ git add .

说明: 除了能够判断出当前目录(包括其子目录)所有被修改或者已删除的文档,
还能判断用户所添加的新文档,并将其信息追加到索引中

git stash(储藏&修改)

当你正在做一项复杂的工作时,发现了一个和当前工作不相关但是又很讨厌的bug 你这时想先修复bug再做手头的工作,那么就可以用 git stash来保存当前的工作状态,等你修复完bug后执行git stash apply就可以回到之前的工作状态。

保存当前的工作状态

  1. $ git stash

进行 fix bug

  1. fix something

提交此次 fix

  1. $ git commit -am "msg"

回到之前的工作状态

  1. $ git stash apply

git tag

标签可以针对某一时间点的版本做标记,常用于版本发布

打标签

  1. $ git tag v1-light # 创建轻量标签
  2. $ git tag -a v1.0 -m "my version 1.0" # 创建附注标签[-a(annotated)]
  3. $ git tag -a v1.1 -m "my version 1.1" # 创建附注标签[-a(annotated)]
  4. $ git tag -a v2.0 -m "my version 2.0" # 创建附注标签[-a(annotated)]

创建轻量标签不需要传递参数,直接指定标签名称即可,轻量级tag不是对象,它就是个指向特定提交对象的引用
创建附注标签时,参数a即annotated的缩写,指定标签类型,后附标签名。参数m指定标签说明,说明信息会保存在标签对象中。

列出标签

  1. $ git tag # 在控制台打印出当前仓库的所有标签
  2. $ git tag -l 'v1.*' # 搜索符合模式的标签

切换到标签

  1. $ git checkout tagname

查看标签信息

  1. $ git show v1.0

删除标签

  1. $ git tag -d v1.0

给指定的commit打标签

  1. $ git tag -a v1.0 9fbc3d0

标签发布

通常的git push不会将标签对象提交到git服务器,我们需要进行显式的操作

  1. $ git push origin v2 # 将`v0.1.2`标签提交到`git`服务器
  2. $ git push origin tags # 将本地所有标签一次性提交到`git`服务器

git archive 打包发表版本

  1. $ git archive --format zip -o filename.zip HEAD

git show 查看各种类型的对象

查看指定版本的文件

  1. $ git show SHA-1

查看指定版本的某个文件

  1. $ git show SHA-1:filename

查看指定tag的文件

  1. $ git show tagname

git branch 分支操作

查看分支

  1. $ git branch

建立分支

  1. $ git branch new_branch


$ git checkout -b new_branch # 创建分支并切换进去

切换分支

  1. $ git checkout another_branch

合并分支

  1. $ git merge branch_name

删除分支

  1. $ git branch -d existBranch # 删除已经合并好的分支
  2. $ git branch -D existBranch # 删除分支不管是否合并好

修改分支名

  1. $ git branch -m oldname newname

git rebase 合并版本

合并多个小版本

  1. $ git rebase -i 分支名(基于哪个分支) 把从第二个pick开始都改成s

更多参考:git-community-book-cn(p50)

git reset 回退版本

  1. $ git reset --hard HEAD # 撤销当前的所有修改,HEAD始终指向最新的 commit 对象
  2. $ git checkout filename # 撤销某个文件里的修改
  3. $ git reset --hard HEAD^ # 撤销上次提交,"不可逆转"
  4.  
  5. $ git checkout SHA-1 # 回到之前的某个版本
  6. $ git checkout master # 回到最新版本

修复提交

  1. $ git reset --soft HEAD^ # 将修改保存到暂存区,可以用`git diff --staged`查看
  2. $ git commit -a -c ORIG_HEAD# 用刚才的HEAD的提交信息来提交

重置多个提交多次修改

  1. $ git reset --mixed SHA-1 # SHA-1是要合并版本的前一个版本的值
  2. $ git add -p # 将不相关的功能分开
  3. $ git commit -m "msg1"
  4. $ git add -p
  5. $ git commit -m "msg2"
  6. $ git checkout master
  7. $ git merge xxx

修改最后一次的提交信息

  1. $ git commit --amend
  2.  
  3. $ git reset [--(mixed|soft|hard)] SHA-1
  • --hard 回退到某次提交完整状态,舍弃提交后的所有修改
  • --mixed 默认模式,回退到某次提交后的未暂存状态
  • --soft 回退到某次提交后的暂存状态

git blame

查看文件的每个部分是谁修改的

  1. $ git blame filename
  2. $ git blame -L 2,+5 filename # 查找从第二开始的五行是谁修改的

.gitignore 忽略某些文件和目录

TODO:全局忽略

一般某个项目开发过程中都会产生一些中间文件,这些文件是我们不想要追踪的。git中可以使用.gitignore文件来忽略这些文件。

在需要的目录下面添加.gitignore文件,其中每一行表示需要忽略的文件的正则表达式。

  • 允许使用空行,没有实际语法作用
  • #开头的行视作注释
  • ! 开头的模式会覆盖之前的定义,将匹配的对象重新加入跟踪列表
  • 以/结尾的模式,git会屏蔽掉该目录及其所有子目录及文件(只屏蔽目录)
  • 不以/结尾的模式,git屏蔽同名的文件名及目录(屏蔽目录和同名文件)
  • 以/开头的模式,git只会屏蔽项目根目录下的匹配对象

示例:

  1. .*.swp
  2. a.out
  3. *~
  4. *.[oa] # 忽略`.o`或`.a`结尾的文件
  5. !libsqlite3.a # 但`libsqlite3.a`除外
  6. /var # 忽略根目录下的 var 目录
  7. bin/ # 忽略`bin/`目录及目录下的所有文件
  8. doc/*.txt # 忽略`doc/`目录下以.txt结尾的文件,但不递归

git默认文件

  • objects 目录存储所有数据内容
  • refs 目录存储指向数据(分支)的提交对象的指针
  • HEAD 文件指向当前分支
  • index 文件保持了暂存去信息

四种对象

blob 用来存储文件内容,通常是一个文件

  1. $ find .git/objects -type f # 查看所有更改的 SHA1
  2. $ git hash-object filename # 计算该文件的 hash 值,
  3. 此时查看`.git/objects/`可以看到有一个以该哈希值前两个字符相同的文件,
  4. 查看这个文件的内容,其内容是剩下的38个字符
  5. $ git show SHA1 # 显示文件的内容

  6. $ git cat-file -p SHA1

tree 有点像一个目录,它管理一些 tree 或是 blob(就像文件和子目录)

commit 表示修改历史,描述一个个 tree 之间如何联系起来

tag 标签(轻量级tag不是对象,附注tag是一个对象,它可以指向 blob, tree和commit,大部分时候是commit)

对象之间的关系(TODO)

  1. $ git log
  2. $ git cat-file -t SHA1 # 查看对象的类型
  3. $ git cat-file commit dcb300a29
  4. $ git show -s --pretty=raw SHA1
  5. $ git ls-tree dcb300a29
  6. $ git cat-file -t 0016606
  7. $ git cat-file blob 0016606

一个commit对象唯一的指向一个tree对象

20个字节 = 20*8位 = 2^160 -1大小的SHA1值

每次提交版本都会生成对应的SHA1值,在git中,会对提交(commit)、文件(blob)、目录(tree)、标签(tag)生成一个唯一的SHA1值,
git就是基于此来得知文件或目录的改动,因为这四类对象计算得到的SHA1值都是唯一的,同时你也可以直接使用SHA1值来指代相应的对象。

远程操作

获取远程代码库

  1. $ git clone git@github.com:ButBueatiful/test.git test_local

输入你在远程主机的用户名和密码,就可以将项目源代码取回到本地。

注意:

  1. 通过git clone获取的远端git库,只包含了远端git库的当前工作分支。如果想获取其它分支信息,需要使用 git branch –r 来查看

  2. 如果需要将远程的其它分支代码也获取过来,可以使用命令git checkout -b 本地分支名 远程分支名,其中,远程分支名为git branch –r所列出的分支名, 一般是诸如origin/分支名的样子。如果本地分支名已经存在, 则不需要-b参数。

将本地分支保存到远程(origin是远程代码库名)

  1. $ git push origin new

删除远程分支

  1. $ git push origin :new # 将远端的`new`分支清空,也就是删除它

更新本地仓库

  1. $ git pull # 从远程获取最新版本并merge到本地
  2. $ git fetch # 从远程获取最新版本到本地,
  3. 不会自动`merge`,在手动`merge`之前可先`diff`一下差异,比较安全

向远程主机提交代码

查看目前本地仓库的状态

  1. $ git status

添加需要更改的代码到仓库

  1. $ git add changed_files
  2. $ git commit -m "更改的内容"

如果添加或删除的代码都需要提交,则可以使用

  1. $ git commit -am "更改的内容"

注意: 提交时请务必填写更新信息,以便于回溯。

如果先建立的是本地仓库的话,需要进行如下操作

首先初始化新的本地仓库

  1. $ mkdir test
  2. $ cd test
  3. $ git init
  4. $ touch README

将文件添加到你的本地git仓库中

  1. $ git add README
  2. $ git commit -m 'first commit'

把你在github上仓库的地址添加进去,注意在远程仓库里必须有该地址

  1. $ git remote add origin 'git@github.com:ButBueatiful/test.git'

提交到github上的远程仓库中:

  1. $ git push -u origin master

如果本地已有git仓库, 请遵循以下操作

  1. $ cd existing_git_repo
  2. $ git remote add origin 'git@github.com:ButBueatiful/test.git'
  3. $ git push -u origin master

misc

列出已暂存的文件

  1. $ git ls-files
  2. $ git checkout -f HEAD # 找回删除的文件

合并多个提交

  1. $ git reset --soft # 开始那个提交的SHA-1
  2. $ git reset --soft HEAD~n (n代表要提交的版本个数加一)
  3. $ git commit --amend

查看文件的对应行是谁修改的

  1. $ git blame filename

用Git工作的一天

  1. 从服务器上clone代码到本机

  2. 在本机上创建分支

  3. 在本机创建的分支上修改、提交代码

  4. 把本机上自己创建的分支合并到主分支上

  5. 新建一个分支,把服务器上最新版的代码fetch下来,然后跟自己的主分支合并

  6. 生成补丁,把补丁发送给主开发者

常见问题

  1. (gnome-ssh-askpass:3422): Gtk-WARNING **: cannot open display:

解决办法

  1. echo 'unset SSH_ASKPASS' >> ~/.bashrc && source ~/.bashrc

相关资源

iOS开发--git的更多相关文章

  1. fir.im Weekly - iOS开发中的Git流程

    本期 fir.im Weekly 收集了微博上的热转资源,包含 Android.iOS 开发工具.源码等好用的轮子,还有一些 APP 设计的 Tips,希望对你有用. 精仿知乎日报 iOS 端 @我偏 ...

  2. GIT在iOS开发中的使用

    前言 在iOS开发中,很多公司对项目的版本控制管理都使用了git,当然也有部分公司使用的是svn.当年我最初接触的是svn,觉得使用起来挺方便的,但是每次切分支都需要下载一份新的代码起来,这实在太麻烦 ...

  3. iOS开发MAC下配置Svn和Git

    如果你对iOS开发中的版本控制还不了解那么你可以先看看这篇(大致看一遍就ok) http://www.cnblogs.com/iCocos/p/4767692.html   关于版本控制使用起来并不难 ...

  4. iOS开发——源代码管理——git(分布式版本控制和集中式版本控制对比,git和SVN对比,git常用指令,搭建GitHub远程仓库,搭建oschina远程仓库 )

    一.git简介 什么是git? git是一款开源的分布式版本控制工具 在世界上所有的分布式版本控制工具中,git是最快.最简单.最流行的   git的起源 作者是Linux之父:Linus Bened ...

  5. iOS 开发不可缺少的工具

    1.截屏利器:Snip 强大的滚动截屏功能,你值得拥有! Snip.png 传送门:http://www.snip.qq.com/ 2.Mac上最好的终端模拟器:iTerm2 iTeam.png 传送 ...

  6. iOS开发之浅谈MVVM的架构设计与团队协作

    今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...

  7. iOS开发之各种动画各种页面切面效果

    因工作原因,有段时间没发表博客了,今天就发表篇博客给大家带来一些干货,切勿错过哦.今天所介绍的主题是关于动画的,在之前的博客中也有用到动画的地方,今天就好好的总结一下iOS开发中常用的动画.说道动画其 ...

  8. IOS 开发中要注意的事项

    1.关于拍摄 TGCameraViewController – 基于 AVFoundation 的自定义相机.样式漂亮,轻量并且可以很容易地集成到 iOS 项目中.不会内存吃紧 2.block 中对控 ...

  9. iOS——学习网址收集+如何提高iOS开发技能

    1 一个比系统自带的终端好用的软件:http://www.iterm2.com 2 学习和遇到技术问题可以去的网站: CocoaChina      http://developer.cocoachi ...

随机推荐

  1. Android实现AppWidget、Broadcast动态注册

    Android实现AppWidget.Broadcast动态注册 开发工具:Andorid Studio 1.3 运行环境:Android 4.4 KitKat 工程内容 主界面可以编辑广播的信息,点 ...

  2. 内核中的 likely() 与 unlikely()

    内核中的 likely() 与 unlikely() 在 2.6 内核中,随处可以见到 likely() 和 unlikely() 的身影,那么为什么要用它们?它们之间有什么区别? 首先要明确: if ...

  3. 设置xx-net,访问youtube等国外网站

    配合使用chrome+xx-net,就可以免费访问youtube等外网了.步骤如下: 1. 按照https://github.com/XX-net/XX-Net/wiki/%E4%BD%BF%E7%9 ...

  4. UITableView 应用及其总结

    Plain: Grouped: Cell的结构图: UITableViewCellStyleDefault:预设使用这种,若左侧ImageView没图的话,只有一行字(textLable.text). ...

  5. 字符串流sstream[part1/基本知识]

    C++中的输入输出分为三种:基于控制台的I/O,即istream.ostream.iostream:基于文件的I/O,即ifstream.ofstream.fstream:基于字符串的I/O,即ist ...

  6. 机器学习&&数据挖掘之一:决策树基础认识

    决策树入门篇 前言:分类是数据挖掘中的主要分析手段,其任务就是对数据集进行学习并构造一个拥有预测功能的分类模型,用于预测未知样本的类标号,把类标号未知的样本按照某一规则映射到预先给定的类标号中. 分类 ...

  7. 推荐系统之LFM

    这里我想给大家介绍另外一种推荐系统,这种算法叫做潜在因子(Latent Factor)算法.这种算法是在NetFlix(没错,就是用大数据捧火<纸牌屋>的那家公司)的推荐算法竞赛中获奖的算 ...

  8. JS 数组的基础知识

    数组 一.定义 1.数组的文字定义 广义上说,数组是相同类型数据的集合.但是对于强类型语言和弱类型语言来说其特点是不一样的.强类型语言数组和集合有以下特点. 数组强类型语言:1.数组里面只能存放相同数 ...

  9. HttpWatch 安装后在IE上打开

    启动浏览器, 在空白地方左键,  显示出菜单栏 菜单栏中选择"查看">"浏览器栏">"HttpWatch"启动HttpWatch ...

  10. ASP.NET中的事件处理

    一.ASP.NET中的事件主要支持3个主要的事件组:1.包含在asp.net生成页面时自动生成,我们使用这些事件建立页面(如page_load等)2.包含了用户与页面交互时发生的所有事件(这种最强大) ...