Git学习笔记 - 1

标签: git 学习 笔记 | 发表时间:2011-06-18 22:31 | 作者:深夜两点 理
出处:http://www.cnblogs.com/

 

ProGit这本书讲的挺不错。循序渐进。有几个命令书中语焉不详,卡住了挺长时间。记录一下。

remote branch

每一个remote branch都会在本地表现为一个不可改变的静态branch。使用git branch -a可以看到。红色的就是remote branch。不能够对这些branch进行改动,但是可以创建一个这些remote branch的tracking branch:

git checkout -b b1 origin/b1
# or
git checkout --tracking origin/b1

这时候,创建出来的local branch就会被git看作是对应的remote branch的tracking branch。在执行git push的时候,local branch的内容就会自动被push到它的tracking branch。

缺省的master就是origin/master的tracking branch。

本地的branch只能够通过向remote branch推送(push)数据的方式来和remote branch交互。如果想创建一个remote branch,就需要创建一个branch,然后

git branch b2
git push origin b2

这两条命令创建一个本地branch b2,然后将它增加到remote branch。这时候运行 git branch -a,能看到有了一个新的remote branch。

 

git fetch

git fetch [remote_repo] :这个是将remote repo所有的数据:包括更新的文件,新增/减的分支,tag,等等,全部下载到本地的local repo。但是,不会做merge。也就是说,master分支数据可能是旧的,但是origin/master上的数据已经是新的了。可以进一步运行

git checkout master
git merge origin/master

来将两个分支进行merge。或者更好使用git push来进行merge(前提是master确实是origin/master的tracking branch)

git pull

git pull [remote_repo branch_name]:这个命令直接从指定remote_repo的指定branch拉取相应的数据。并将远程branch的更新和本地的tracking branch做merge。

注意。这时候,并不会把这个branch之外的数据拉下来。比如,如果远程的另一个branch有更新,或者增加了一个新的branch,这个命令并不会把这些数据拉下来。

如果直接执行git pull [remote_repo],则会将所有数据拉下来,包括其它分支的更新,包括新增的分支。同时还会将当前branch与它tracking的branch做merge。

git push

git push [remote_repo local branch:remote branch]。缺省情况下,将当前branch的改动push到缺省repo中它track的branch。也可以加repo和branch,将当前分支的数据push到任何一个repo的任何一个branch

删除远程分支

如果需要删除一个远程分支,则需要git push origin :b1根据 git push的定义,就是把空push到远程的b1 branch。也就是删除了。

但是,如果别人已经在b1删除之前执行了fetch或者pull,在本地有了b1这个branch,再次执行fetch或者pull并不会删除这个branch。运行git branch -a也不能看出这个branch被删除了。这时候需要运行

$ git remote show origin
* remote origin
  Fetch URL: [email protected]:xxx/xxx.git
  Push  URL: [email protected]:xxx/xxx.git
  HEAD branch: master
  Remote branches:
    master                 tracked
    refs/remotes/origin/b1 stale (use 'git remote prune' to remove)
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)

这时候能够看到b1是stale的,可以使用git remote prune origin将它从本地repo也去掉。

 

Rebase

rebase就是re-base。git每个commit都有一个parent指针指向当前提交的parent,即base。rebase则是改变commit的parent,这样的好处是可以减少版本树的分支和复杂度,坏处是用不好的话会给别人带来很多麻烦。

假设有一个master:7,branch f1是从master:7上cut出来的一个branch。f1是一个local的branch,用来开发一个feature。

在开发feature的时候,有人将一些修改commit到了master上。

在feature做了一个阶段之后,master已经有了版本10。f1有了版本5。这时候想把f1上的修改合并到master上。首先执行git pull把master上的更新都拉到本地来。然后可以使用rebase命令将f1上的改动都rebase(gitpro上翻译为衍合,我觉得拟合也挺好,至少是个现有的词)到master上,然后进行提交。

git checkout f1
git rebase master
#or
git rebase master f1

这时候,git会先找到f1和master的交点,也就是cut f1的时候的版本(master:7),从这个版本开始,git将f1每次的提交作为一个diff文件保存起来。然后checkout master,将这些diff一个个应用到master上。

看起来很像是merge,不过merge会产生一个新的提交,而rebase是re-base,也就是改变f1的每个提交:改变每个提交的parent,改变每个提交指向的文件快照。让整个过程看起来好像就没有f1一样,所有的改动都是直接在master上来的。Rebase过之后,如果feature已经做完,f1可以直接被删掉。

merge则会产生一个新的提交,不改变已有的提交。好处是比较安全,历史不会被改动。不好之处就是版本树会比较乱。

rebase很好很清爽。需要注意的一点是“永远不要rebase那些已经推送到远程repo的更新(commit)”

rebase会改变commits的内容,也就是改变历史,对于没有push到server上的commits无所谓,反正只有本地一个人在用。这时候使用rebase将commits rebase到公共branch(master),可以让本地的历史更清爽。

对于一个已经push到remote repo的commits。比如f1如果已经在remote repo上了,而且,f1:1到f1:3已经push到repo上了。这时候如果再将f1:1到f1:5 rebase到master上,然后强制push到repo上,结果就是f1这个branch的历史被改动。当然,如果这个remote branch只有一个人用,也还无所谓。如果有人在f1:3的时候cut出来一个branch,这时候那个人就悲剧了。再次pull的时候,将会收到rebase后改动的commits,以及原来就有的commits,情况会变的异常糟糕。

如果是push到master上,影响将更大。

总之,remote repo上的commit永远不要改动。也就是说,永远不要将已经push出去的commit再rebase一下。rebase也无所谓,切不要push出去也不会对别人造成影响。如果push出去了,这样改变了history,改变了server上的版本树,情况就糟糕了。

具体图和例子请参照Git Pro

http://progit.org/book/zh/ch3-6.html

作者: 深夜两点 发表于 2011-06-18 22:31 原文链接

评论: 0 查看评论 发表评论


最新新闻:
· 诺基亚质疑IPCom专利案裁决(2011-06-19 17:17)
· Doodle:父亲节快乐 2011(2011-06-19 17:05)
· 硅谷初创公司十亿美元俱乐部盘点(2011-06-19 16:46)
· Techcrunch:网络将呈游戏化趋势 参与度很重要(2011-06-19 15:50)
· 世嘉遭黑客袭击 用户信息泄漏(2011-06-19 13:52)

编辑推荐:Kinect for Windows SDK开发初体验(二)操作Camera

网站导航:博客园首页  我的园子  新闻  闪存  小组  博问  知识库

相关 [git 学习 笔记] 推荐:

Git学习笔记 - 1

- 理 - 博客园-首页原创精华区
ProGit这本书讲的挺不错. 有几个命令书中语焉不详,卡住了挺长时间. 每一个remote branch都会在本地表现为一个不可改变的静态branch. 使用git branch -a可以看到. 红色的就是remote branch. 不能够对这些branch进行改动,但是可以创建一个这些remote branch的tracking branch:.

git 速成(学习资料)

- - CSDN博客研发管理推荐文章
可以参照: http://www.bootcss.com/p/git-guide/ 进行学习. 简介:git 主要由三部分组成.             2: index(缓冲区)--其实就是索引\缓冲区 临时保存你的修改;.    3: HEAD  --最后是 HEAD,指向你最近一次提交后的结果.

shell 学习笔记

- tiger - 游戏人生
将脚本目录加到 PATH 中. 在 dash 中如何进行字符串替换. 将 rst 格式文档转换为 blog 可用的 html 代码. shell 脚本虽然不是非常复杂的程序, 但对于首次接触的我来讲, 多少还是有些忌惮. 不过, 接触任何新事物都需要勇敢面对, 逐步树立信心. 我是冲着把脚本写好去的, 所以, 我的目标是能够写出友好, 健壮, 优美的脚本..

OAuth学习笔记

- 宋大妈 - FeedzShare
来自: 标点符 - FeedzShare  . 发布时间:2011年08月29日,  已有 2 人推荐. OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. OAuth允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据.

Vim学习笔记

- 临池学书 - C++博客-首页原创精华区
最近在学习Vimtutor中的相关内容,Vim的使用博大精深,很多命令一旦不使用就会忘记,下面把其中的没有使用到的相关命令做一个简单的总结,供以后复习使用. 至于常见的保存,插入等等命令,则不予记录,在以后的使用中加深练习即可. To change until the end of a word, type  ce (ce + 修正的单词).

OAuth学习笔记

- jiaosq - 标点符
OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. OAuth允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据. 每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频).

HTML学习笔记

- - CSDN博客推荐文章
超文本标记语言( 英文:HyperText Markup Language,HTML)是为“ 网页创建和其它可在 网页浏览器中看到的信息”设计的一种 标记语言. HTML被用来结构化信息——例如标题、段落和列表等等  点击打开链接. w3schools  点击打开链接 {语法大全,超赞.

jQuery学习笔记

- - ITeye博客
什么是jQuery,它能为我们做什么. jQuery是一个javascript类库或称之为javascript框架. 无需刷新页面从服务器获取信息. 简化常见的javascript任务. 为什么会如此流行或说得到大量用户群的支持:. 多重操作集于一行(避免使用临时变量或不必要的重复代码). jQuery利用了CSS选择符的能力,在DOM中快捷而轻松地获取元素或元素集合.

JdbcTemplate学习笔记

- - SQL - 编程语言 - ITeye博客
1、使用JdbcTemplate的execute()方法执行SQL语句. 2、如果是UPDATE或INSERT,用update()方法.    JdbcTemplate将我们使用的JDBC的流程封装起来,包括了异常的捕捉、SQL的执行、查询结果的转换等等. spring大量使用Template Method模式来封装固定流程的动作,XXXTemplate等类别都是基于这种方式的实现.

Disruptor 学习笔记

- - 开源软件 - ITeye博客
Disruptor 是一个高性能异步处理框架,也可以认为是一个消息框架,它实现了观察者模式. Disruptor 比传统的基于锁的消息框架的优势在于:它是无锁的、CPU友好;它不会清除缓存中的数据,只会覆盖,降低了垃圾回收机制启动的频率. Disruptor 为什么快. 通过内存屏障和原子性的CAS操作替换锁.