Git

来自tomtalk
跳转至: 导航搜索

《Pro Git》网页版

https://git-scm.com/book/zh/v2

1 起步

关于版本控制
  • 本地版本控制系统
  • 集中化的版本控制系统
  • 分布式版本控制系统
Git历史

1991-2002年间:绝大多数的 Linux 内核维护工作都花在了提交补丁和保存归档的繁琐事务上。

2002-2005年:整个项目组开始使用用分布式版本控制系统BitKeeper来管理和维护代码。

2005年:BitKeeper不再免费使用了。迫使Linux开源社区开发一套属于自己的版本控制系统。他们对新的系统制订了若干目标:

  • 速度
  • 简单的设计
  • 对非线性开发模式的强力支持(允许上千个并行开发的分支)
  • 完全分布式
  • 有能力高效管理类似 Linux 内核一样的超大规模项目(速度和数据量)
Git 基础
  • 直接记录快照,而非差异比较

Git 和其他版本控制系统的主要差别在于,Git 只关心文件数据的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异。

  • 近乎所有操作都是本地执行
  • 时刻保持数据完整性

Git使用SHA-1算法计算数据的校验和,通过对文件的内容或目录的结构计算出一个SHA-1哈希值,作为指纹字符串。 这项特性作为Git的设计哲学,建在整体架构的最底层。所以如果文件在传输时变得不完整,或者磁盘损坏导致文件数据缺失,Git都能立即察觉。

  • 多数操作仅添加数据
  • 文件的三种状态:committed,modified和staged。

2 基础

获取 Git 仓库

在现有目录中初始化仓库

git init

克隆现有的仓库

如果你对其它的 VCS 系统(比如说Subversion)很熟悉,请留心一下你所使用的命令是"clone"而不是"checkout"。 这是 Git 区别于其它版本控制系统的一个重要特性,Git 克隆的是该 Git 仓库服务器上的几乎所有数据,而不是仅仅复制完成你的工作所需要文件。 当你执行 git

clone 命令的时候,默认配置下远程 Git 仓库中的每一个文件的每一个版本都将被拉取下来。 事实上,如果你的服务器的磁盘坏掉了,你通常可以使用任何一个克隆下来的用户端来重建服务器上的仓库(虽然可能会丢失某些服务器端的挂钩设置,但是所有版本的数据仍在。

记录每次更新到仓库

工作目录下面的所有文件都不外乎这两种状态:已跟踪或未跟踪。

状态简览

$ git status -s

远程仓库的使用

查看远程仓库

git remote -v

添加远程仓库

git remote add pb https://github.com/paulboone/ticgit

检出标签

在Git中你并不能真的检出一个标签,因为它们并不能像分支一样来回移动。

git checkout -b [branchname] [tagname]

$ git checkout -b version2 v2.0.0

3 分支

接下来,我们将学习 Git 的必杀技特性:分支模型。

5 分布式git

5.1 分布式工作流程

  • 集中式工作流:这就好比是在用Subversion或其他 CVCS)一样,绝大多数人都熟悉和了解这种模式的工作方式,所以使用也非常广泛。
  • 集成管理员工作流:在 GitHub 网站上使用得最多的就是这种工作流。
  • 司令官与副官工作流:这种工作流程并不常用,只有当项目极为庞杂,或者需要多级别管理时,才会体现出优势。

5.2 为项目作贡献

提交指南
本次更新的简要描述(50 个字符以内)
 
如果必要,此处展开详尽阐述。段落宽度限定在 72 个字符以内。
某些情况下,第一行的简要描述将用作邮件标题,其余部分作为邮件正文。
其间的空行是必要的,以区分两者(当然没有正文另当别论)。
如果并在一起,rebase 这样的工具就可能会迷惑。
 
另起空行后,再进一步补充其他说明。
 
 - 可以使用这样的条目列举式。
 
 - 一般以单个空格紧跟短划线或者星号作为每项条目的起始符。每个条目间用一空行隔开。
   不过这里按自己项目的约定,可以略作变化。
私有的小型团队

John 的推送操作被驳回,因为 Jessica 已经推送了新的数据上去。请注意,特别是你用惯了 Subversion 的话,这里其实修改的是两个文件,而不是同一个文件的同一个地方。Subversion 会在服务器端自动合并提交上来的更新,而 Git 则必须先在本地合并后才能推送。

私有团队间协作

现在我们来看更大一点规模的私有团队协作。如果有几个小组分头负责若干特性的开发和集成,那他们之间的协作过程是怎样的。

假设 John 和 Jessica 一起负责开发某项特性 A,而同时 Jessica 和 Josie 一起负责开发另一项功能 B。公司使用典型的集成管理员式工作流,每个组都有一名管理员负责集成本组代码,及更新项目主仓库的master 分支。所有开发都在代表小组的分支上进行。

git push -u origin featureB:featureBee  #引用规格

通过featureA共享代码:

$ git checkout featureA
Switched to branch 'featureA'
$ git merge origin/featureA
Updating 3300904..aad881d
Fast forward
     lib/simplegit.rb |   10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
公开的小型项目
公开的大型项目

5.3 项目的管理

使用特性分支进行工作 采纳来自邮件的补丁 检出远程分支 决断代码取舍 代码集成 给发行版签名 生成内部版本号 准备发布 制作简报

Git工作流指南

https://github.com/xirong/my-git/blob/master/git-workflow-tutorial.md

Git三大特色之Stage(暂存区)

Git三大特色之Branch(分支)

Git三大特色之WorkFlow(工作流)

Git flow工作流

http://blog.tomtalk.net/uploads/e1cc9546f886773e0a3e344cf3ad80fa.png

初始化git flow,它会问你一系列的问题,蛋定!尽量使用它的默认值就好了。

$ git flow init   
No branches exist yet. Base branches must be created now.
Branch name for production releases: [master]
Branch name for "next release" development: [develop]
How to name your supporting branch prefixes?
Feature branches? [feature/]
Release branches? [release/]
Hotfix branches? [hotfix/]
Support branches? [support/]
Version tag prefix? []

开发流程小结:

git flow feature start xxx.1.0 (它会基于develop开一个分支,用于功能开发)
git flow release start xxx.1.2 (它会基于develop开一个分支,用于提测和bug修复)
git flow hotfix start xxx.1.2 (它会基于master开一个分支,用于线上bug紧急修复)
...
git flow feature finish xxx.1.0 (它会merge到develop上)
git flow release finish xxx.1.2(它会merge回master和develop)
git flow hotfix finish xxx.1.3(它会merge回master和develop)

Master: 最近发布到生产环境的代码。

Hotfix: 热修复分支,线上项目出现debug修复时使用。

Release: 测试分支,下一个发布版本由此诞生,debug的聚集地。

Develop: 主开发分支,功能分支由此检出,功能分支的最终归宿。

Feature: 功能分支。

http://danielkummer.github.io/git-flow-cheatsheet/index.zh_CN.html git-flow 备忘清单

http://www.bkjia.com/Javabc/1156134.html git flow的使用

git flow release start报错,提示要完成上一个release,才能新建,怎么办?

把本地的release分支删了,git flow在客户端只允许同时存在一个release和一个Hotfix。

gitlab

git命令之git fetch的用法

这里需要解释下什么是FETCH_HEAD?

FETCH_HEAD指的是:某个branch在服务器上的最新状态。每一个执行过fetch操作的项目都会存在一个FETCH_HEAD列表,这个列表保存在.Git/FETCH_HEAD文件中,其中每一行对应于远程服务器的一个分支。当前分支指向的FETCH_HEAD,就是这个文件第一行对应的那个分支。

一般来说,存在两种情况:

  1. 如果没有显式的指定远程分支,则远程分支的master将作为默认的FETCH_HEAD。
  2. 如果指定了远程分支,就将这个远程分支作为FETCH_HEAD。

常见的git fetch使用方式包含以下四种:

git fetch

这一步其实是执行了两个关键操作:

  1. 创建并更新所有远程分支的本地远程分支。
  2. 设定当前分支的FETCH_HEAD为远程服务器的master分支(上面说的第一种情况)
git fetch origin

同上,只不过手动指定了remote。

git fetch origin branch1

设定当前分支的FETCH_HEAD'为远程服务器的branch1分支`。

注意:在这种情况下,不会在本地创建本地远程分支,这是因为:

  1. 这个操作是git pull origin branch1的第一步,而对应的pull操作,并不会在本地创建新的branch。
  1. 这个命令可以用来测试远程主机的远程分支branch1是否存在,如果存在,返回0,如果不存在,返回128,抛出一个异常。
git fetch origin branch1
branch2

只要明白了上面的含义,这个就很简单了,

  1. 首先执行上面的fetch操作
  2. 使用远程branch1分支在本地创建branch2(但不会切换到该分支),
  3. 如果本地不存在branch2分支,则会自动创建一个新的branch2分支,
  4. 如果本地存在branch2分支,并且是`fast forward',则自动合并两个分支,否则,会阻止以上操作。
git fetch origin 
branch2

等价于: git fetch origin master:branch2

fetch和pull的区别

git fetch:从远程获取最新版本到本地,不会自动merge。

git pull:从远程获取最新版本并merge到本地。

配置Git支持大小写敏感

  1. 在新建代码文件时,不注意把文件名应该小小写搞错了
  2. 文件已经push到远程了
  3. 在windows下面将文件名字改为全小写

改好后,在Git中没有任何反应,使用git status时,如果遇到下面情况,说明GIT大小写不敏感, 如何解决Git的大小不敏感问题呢?

  1. 设置Git大小写敏感 ignorecase = false
  2. 先删除文件,再添加进去
  3. 使用git的rename命令

.config

user]
	name = tecshuttle
	email = tecshuttle@gmail.com
[core]
	autocrlf = true
        ignorecase = false
[credential]    
        helper = store

TortoiseGit保存用户名密码的方法

  1. Windows中添加一个HOME环境变量,值为%USERPROFILE%
  2. 在“开始>运行”中打开%Home%,新建一个名为“_netrc”的文件
  3. 用记事本打开_netrc文件,输入Git服务器名、用户名、密码,并保存:
machine github.com    #git服务器名称
login tom.xie         #git帐号
password tecshuttle   #git密码

让TortoiseGit记住帐号密码

在"C:\Documents and Settings\Administrator\.gitconfig" 文件 或 "项目/.git/config"文件 里增加两行(windows用wincred):

[credential]    
    helper = store
[credential]    
    helper = wincred

帐号密码信息会保存在 C:\Documents and Settings\Administrator\.git-credentials里。

分支

创建

$ git checkout -b iss53
#这相当于执行下面这两条命令
$ git branch iss53
$ git checkout iss53

合并

$ git checkout master
$ git merge hotfix

删除

git branch -d hotfix

查看分支

$ git branch -a     #查看远程分支
$ git branch        #查看本地分支

Git撤销git commit但是未git push的修改

git log                    # 找到你想撤销的commit_id
git reset --hard commit_id # 完成撤销,同时将代码恢复到前一commit_id 对应的版本。
git reset commit_id        # 完成Commit命令的撤销,但是不对代码修改进行撤销,可以直接通过git commit 重新提交对本地代码的修改。
git reset --hard HEAD^     # 回退到最近的已提交版本
git reset --hard HEAD~     # 回退到上一个版本 
git reset --hard HEAD~100  # 回退到100个版本

解决Git中fatal: refusing to merge unrelated histories

git merge master --allow-unrelated-histories

Git基本常用命令

git init                     把当前的目录变成可以管理的git仓库,生成隐藏.git文件。
 
git add XX                   把xx文件添加到暂存区去。
 
git diff  XX                 查看XX文件修改了那些内容
 
git log                      查看历史记录
 
git log --pretty=oneline   
 
git log --pretty=oneline -5  只显示5行  
 
cat XX                       查看XX文件内容
 
git reflog                   查看历史记录的版本号id
 
git checkout -XX             把XX文件在工作区的修改全部撤销。
 
git rm XX                    删除XX文件
 
git remote add origin https://github.com/tugenhua0707/testgit  关联一个远程库
 
git push -u origin master                                      把当前master分支推送到远程库。(第一次要用-u 以后不需要)
 
git clone https://github.com/tugenhua0707/testgit              从远程库中克隆
 
git checkout --文件名    撤销单个文件的修改
 
git checkout .          撤销工作区中所有文件的修改
 
git checkout -b dev     创建dev分支 并切换到dev分支上
 
git checkout b0362a895d39061c0bc6f05c575af47de1b3f702   获取指定的历史版本代码
 
git merge dev           在当前的分支上合并dev分支
 
git branch -d dev       删除dev分支
 
git branch name         创建分支
 
git stash               把当前的工作隐藏起来 等以后恢复现场后继续工作
 
git stash list          查看所有被隐藏的文件列表
 
git stash apply         恢复被隐藏的文件,但是内容不删除
 
git stash drop          删除文件
 
git stash pop           恢复文件的同时 也删除文件
 
git remote              查看远程库的信息
 
git remote -v           查看远程库的详细信息
 
git push origin master  Git会把master分支推送到远程库对应的远程分支上
 
# 改名
git mv casesensitive tmp
git mv tmp CaseSensitive
 
#tag
git tag -a v1.4 -m "my version 1.4"  打tag
git push origin --tags               把本地所有tag推送到远端
git checkout -b branch_name tag_name 签出tag

Git使用基础篇

http://www.open-open.com/lib/view/open1332904495999.html

git clone https://github.com/tecshuttle/zenho_xs.git zenho_xs
git pull
git push
 
git diff application/views/products/detail.php
git commit  -m 'product detail' application/views/products/detail.php  #提交单个文件
 
git add -A                 #添加所有未加入版本控件的文件
 
git stash                  #取消本地修改。新加的文件还在,但所有的修改都会抹去。
git checkout xxxxx(文件名) #取消对某文件的修改。
 
git branch                 #查看当前所有的分支
git checkout branchname    #切换分支

github Contributions Calendar不记录的问题

右键 settings -> Git -> User Info 改邮件名,与github帐户一致就好了。

git仓库中嵌套另一个git仓库

问题

如果在一个git仓库中嵌套了一个git仓库,那么被嵌套的git仓库的改动,不能被大git仓库检测到。 即:仓库A的代码中包含仓库B,A不会检测到B的改动。但是我们常常会在代码中引入其他仓库,那应该怎么解决呢?

解决方案

我们可以使用submodule,我们在引入子仓库时,使用如下命令即可:

git submodule add https://github.com/tecshuttle/moduleA.git
git submodule add https://github.com/tecshuttle/moduleB.git

作用类似git clone,但是他会在父仓库的下面新建.gitmodules文件,并且包含以下内容

[submodule "moduleA"]
	path = moduleA
	url = https://github.com/tecshuttle/moduleA.git
[submodule "moduleB"]
	path = moduleB
	url = https://github.com/tecshuttle/moduleB.git

这一段表示子仓库的位置,以及子仓库的远程仓库的地址。

当我们删除子仓库并且commit之后,这个文件和这个子仓库有关的部分就会消失。

测试步骤

1. 先修改一下子项目的文件,父项目可以感知到变化吗?

  能。

2. 可以提交吗?

  不能。子项目的修改,一定要在子项目内提交。

3. 同时修改父项目和子项目文件,如何提交?

  先完成子项目的提交,再提交父项目的修改。

Install git on CentOS

I wanted to put git on one of my CentOS 5.5 servers. Following the links to download the source led to a web page advising to install with yum. But when I tried,

# yum install git
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.usc.edu
* extras: mirrors.usc.edu
* updates: mirrors.usc.edu
Setting up Install Process
No package git available.
Nothing to do

frustrating! Here’s the solution, add the webtatic repository first:

# Add the repository
rpm -Uvh http://repo.webtatic.com/yum/centos/5/latest.rpm
 
# Install the latest version of git
yum install --enablerepo=webtatic git-all

a lot of dependencies were installed and updated. I didn’t need the workaround mentioned, but in case someone else might: To work around Missing Dependency: perl(Git) errors:

yum install --enablerepo=webtatic --disableexcludes=main git-all

git安装

wget http://www.codemonkey.org.uk/projects/git-snapshots/git/git-latest.tar.gz 
tar xzvf git-latest.tar.gz 
cd git-{date} 
./configure
make && make install


安装错误处理

git: error while loading shared libraries: libiconv.so.2:

这是由于无法加载libiconv.so.2库文件。解决方法:

echo "/usr/local/lib" >> /etc/ld.so.conf
/sbin/ldconfig

Linux的XZ压缩

http://blog.csdn.net/wendaotaoa/article/details/8147496