博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
git fetch或pull前检查remote有哪些变化
阅读量:6302 次
发布时间:2019-06-22

本文共 4430 字,大约阅读时间需要 14 分钟。

hot3.png

http://stackoverflow.com/questions/4944376/how-to-check-real-git-diff-before-merging-from-remote-

Since this topic comes up frequently, and can be confusing without a bit of background on how git works, I thought I'd try to explain the simplest case possible, but with sufficient depth that newcomers will have enough of a handle on it to do additional research.

If you set up your git repository via a normal 'clone' and have the default refspecs, meaning that your remote is named 'origin' and you pull/fetch from the branch 'master', you may sometimes need to see what's in the remote repository before pulling it down.

Since the "git pull" does an automatic merge (unless there are conflicts), it can be nice to see what's "incoming" next. If you're not familiar with how git works, and how refspecs in particular are managed, this can be a bit non-intuitive.

Suppose someone makes a change in the remote repository (for sake of illustration, adding a line to the remote repository by committing a change and pushing it), and you type:

$ git diff origin/master

You probably won't see any changes; however if you do the following:

$ git fetch; git diff ..origin/master

you'll see the difference between what's been committed to your local git repository and what's in the remote repository. You will NOT see any changes which are in your local filesystem or staged in your index.

Ok, why do we do this? origin/master is a refspec (see man pages). In short, this is what we refer to in order to compare against, pull or fetch from, and push to. All of the following are functionally equivalent:

origin/masterremotes/origin/masterrefs/remotes/origin/master

To begin to untangle this, just take a peek at your repository's .git directory structure. A typical layout looks like this:

.git/refs.git/refs/heads.git/refs/heads/master.git/refs/remotes.git/refs/remotes/origin.git/refs/remotes/origin/HEAD.git/refs/remotes/origin/master.git/refs/tags

Look at .git/refs/remotes/origin/HEAD; in the default case it will point to the branch you use to pull from and push to. In my case, since I'm on master, the contents of this text file look like this:

ref: refs/remotes/origin/master

This tells me that the HEAD of my remote is identified by the refspec 'refs/remotes/origin/master'(which happens to have the aliases mentioned above).

This doesn't tell us much; what's the state of the remote repository? Look at the state of the remote master:

$ cat .git/refs/heads/master     6d0fb0adfdfa5af861931bb06d34100b349f1d63

Ok, it's a SHA1 hash; probably a commit. How does it get put in this file? Well, whenever you do a pull or a fetch, this file is updated with the most recent commit from the remote which was pulled or fetched. This explains why we have to git fetch prior to performing the diff. Remember, git fetch just updates your local copy of a remote branch, but doesn't merge it with your working copy. It is completely safe. A git fetch; git merge is equivalent to a git pull.

Once you do the fetch, git will be able to see the most recent commit in the remote repository as of the time of the fetch.

You can use various combinations of specifiers to git to see your diffs as you desire (the following examples use the local working copy as the implicit first commit):

$ git diff remote/origin   This shows the incoming remote additions as deletions; any additions in your local repository are shown as additions.$ git diff ...remote/originShows incoming remote additions as additions; the triple-dot excludes changescommitted to your local repository.$ git diff ..remote/originShows incoming remote additions as additions; the double-dot includes changescommitted to your local repository as deletions (since they are not yet pushed).

For info on ".." vs "..." see git help diff as well as the excellent documentation at  Briefly, for the examples above, double-dot syntax shows all commits reachable from origin/master but not your working copy. Likewise, the triple-dot syntax shows all the commits reachable from either commit (implicit working copy, remote/origin) but not from both.

I'm going through this step by step because I'm fairly new to git and this is exactly the type of thing that had me confused... I'm sure that git experts can find flaws with the details... I just hope this answer bridges the gap for some people who find all the various posts a bit terse.

转载于:https://my.oschina.net/uniquejava/blog/496661

你可能感兴趣的文章
关于测量数据用于团队改进的一些事儿
查看>>
SFTP和FTP的区别
查看>>
配置oracle11g EM db control
查看>>
我的友情链接
查看>>
VirtualBox安装HMC_V7R760的安装
查看>>
Oracle安装完成后重新安装EM过程
查看>>
Spring+Velocity模板发送邮件
查看>>
帧中继中Ospf的网络类型
查看>>
调用xUtils-master的api实现下载
查看>>
ping命令使用范例
查看>>
我的友情链接
查看>>
html中div中引入另一个html页面
查看>>
我的友情链接
查看>>
关于NSRunloop的个人理解!!!!!!
查看>>
我的友情链接
查看>>
关于AJAX框架介绍
查看>>
功能测试的测试工作流程
查看>>
送Vcenter数据库导出虚拟机主要信息报表
查看>>
逻辑卷管理器(LVM)
查看>>
一个小代码,欢迎大佬的意见,求指正
查看>>