0

I need help understandign git pull/fetch merge, etc... I know there are a lot of articles and answers on this site, so I will put it in a context of the problem I have

  1. So, I have this:

    Remote branch "myBranch"
    file A
    file B
    
    Local Branch "myBranch"
           file A
           file B 
    

At this point, these 2 branches are the same

2.) I go ahead and manually create an additional file on remote branch. Imitating as if ANOTHER developer commited it So, the picture changes

    Remote branch "myBranch"
    file A
    file B
    file C *

   Local Branch "myBranch"
           file A
           file B 

Now, I know that git fetch command will "tell me" that there are changes, but will not modify my local branch. When I run git fetch, I get the following output

    $ git fetch
    remote: Counting objects: 4, done.
    remote: Compressing objects: 100% (3/3), done.
    remote: Total 4 (delta 1), reused 0 (delta 0), pack-reused 0
    Unpacking objects: 100% (4/4), done.
    From https://bvdevgithubvm.broadviewnet.com/internal-dev/bvn-process-history-service
       0c075bc..6098e63  prototype  -> origin/prototype

BUT !! I only know that there are differences. How do I know WHAT CHANGED. Can I see the changes on remote branch BEFORE I bring it to my local branch (to my local machine)
I guess, what I am looking for, is if you know SVN world, something equivalent to being able to see svn log and see who commited what, before doing an SVN update.

This was a part 1 of the question I had. Now goes part 2, that may be viewed as independent question.

3.) So, from above I call git pull and bring the remote modification to the local branch So, the picture now is

Remote branch "myBranch"
           file A
           file B
           file C

        Local Branch "myBranch"
           file A
           file B
           file C

At this point branches are the same.

So, I go ahead and delete the file C from my local branch. Then I commit the changes, but DO NOT push them. (yet)!!

At this point the picture is like this:

    Remote branch "myBranch"
           file A
           file B
           file C

        Local Branch "myBranch"
           file A
           file B

Now, this is where I get confused. If I do the git fetch or git pull, output is

$ git pull
    Already up to date.

I EXPECTED to know that there is something on a remote branch that makes it different. But .. I can't ?
How can I deal with this?
Now, I understand that there may be a reason for such behavior, reason that lies in git filosophy, compared to the SVN (for instance). But, how I can deal with such a difference? How can I know that things might have changed on the remote?

Dmitriy Ryabin
  • 363
  • 3
  • 16
  • To make sense out of Git, remember that Git isn't really about *files*. It's about *commits*. Each commit has a full snapshot of the entire source tree, frozen forever in time. Unlike SVN where there's a single central server who can see everything, every individual Git repo just has whatever commits it has. You connect two Git repos and have one get (`fetch`) commits from the other, or give (`push`) commits to the other. This all works by commit hash IDs, which are common across all Gits, but uses a *name* (branch or tag name) to find the *last* commit, from which it works backwards. – torek Dec 03 '19 at 20:49
  • Rather than worrying about remote *branches* and local *branches*, you're always interested in commits. But the hash IDs look random and are useless to humans, so we add names: your branch names, which identify the *last* commit in each of your branches. They add names too: their branch names. You connect your Git to their Git (`git fetch`), get their latest commits, and then your Git updates your memory of their branch names—your `origin/master`, for instance—based on the commit hash ID they said was their branch name (their `master`). – torek Dec 03 '19 at 20:51
  • The bottom line ends up being: you use your memory of their name, your `origin/master` for instance, to get the hash ID of their commit (which may or may not also be your commit, but you have it in your repository). You must run `git fetch` to pick up any change to their names and/or any new commits they have. After that, you can use your *remote-tracking name* `origin/master` to access their latest commit. By definition, your name `master` is your latest commit—your name holds the hash ID of your last commit. Stuff a new hash ID into a name, and that's the latest commit for that name. – torek Dec 03 '19 at 20:53
  • The oddball in all of this is `git pull`. This command perhaps shouldn't exist, but for some people, it's very convenient. It means: *run `git fetch`, then run a second Git command.* The *second* command is the one you will use to incorporate their latest commit(s) into your current branch. But if you want to see what they did, *don't* run the second command yet: use `git fetch`, not `git pull`, so that you just get their new commits. – torek Dec 03 '19 at 20:55

2 Answers2

1

I think you are stuck in svn world... you need to get out of it because your vision about things will be kind of broken.

First, don't think in terms of what the files look like... think in terms of what the revisions are (because that's what git actually works on)... that's why if you look around SO, you will notice that sooooo many questions are related to the way revisions are set up in different branches, not so much about what files are in there (some questions do deal with that stuff, for sure... but most are related to revisions and how to deal with them).

So, first question:

git diff --name-status remote/branchx # see what files changed
git diff remote/branchx # see the diff between both branches
git log HEAD remote/branchx # show the revisions that separate both branches

Now, about your second questions.... your local branch moved, sure... but the remote hasn't so if you try to fetch, there will be no movement of the remote references on the local repo DB (you local repo's remote pointers are already set there and also the tip of the remote branch that you are tracking is already part of the history of your branch)... that's what git is telling you.

eftshift0
  • 26,375
  • 3
  • 36
  • 60
  • Thanks. "--name-status" parameter - is what I did not know about. Useful. I was always using only git diff. (and git difftool, with the connected beyond compare) – Dmitriy Ryabin Dec 03 '19 at 19:08
1

How do I know WHAT CHANGED. Can I see the changes on remote branch BEFORE I bring it to my local branch (to my local machine)

Sure. Do a git diff between the remote and local branches, as explained in How to compare a local git branch with its remote branch?.

So, I go ahead and delete the file C from my local branch. Then I commit the changes, but DO NOT push them. (yet)!!...I EXPECTED to know that there is something on a remote branch that makes it different. But .. I can't? How can I deal with this?

If you look at the log of the remote branch, you'll see a list of commits. If you look at the log of the local branch, you'll see a similar list of commits, except that the local branch has one more, namely the commit where you deleted file C. That's a newer change than anything on the server; git tells you that your local branch is up to date with the remote branch because the local branch has every commit that's in the remote branch, and then some. Being up to date also means that you can push your changes to the remote branch with no problem; when you do, the remote will get your new commit that deletes file C, and the repos will again match.

If you want to see how your local branch differs from the remote branch, you can again use git diff as above.

Consider what would happen if someone else changed the remote branch. Their change might not conflict with anything you've done -- for example, they just added a file D. In that case, your changes don't conflict with the remote branch, so you can probably still push up your change with no problem. Or, they might do something that does conflict with your version; perhaps they changed file C. In that case, git can't know whether their change to file C or yours is the right one to keep, so you'll need to manually resolve that conflict before you can push your changes to the remote.

Caleb
  • 124,013
  • 19
  • 183
  • 272
  • Thank you. I suppose I was looking for a one stop answer. I just have to remember to always do "git diff" before doing anything that can potentially change balances between local and remote. – Dmitriy Ryabin Dec 03 '19 at 19:19
  • @DmitriyRyabin In practice, it's really not necessary to do that all the time. A lot of it probably comes down to how you and your team work together, but with git it's easy to back out most changes. If Github is an option for your remote repo(s), use it... most of the time when I'm looking at changes between branches, it's in Github. – Caleb Dec 03 '19 at 20:56
  • yes, it is an option now - and a direction to be the only option soon. Team does not really communicate verbally, and all are in different cities - so what I see in git, is the only thing out there to see. Hence these questions, so not to mess things up. – Dmitriy Ryabin Dec 04 '19 at 15:18