5

I am learning git/github/version control and I found the diagram below really useful (source). My question is where does git merge fit into this diagram? Where would the arrow start and point to?

enter image description here

piccolo
  • 1,593
  • 15
  • 34
  • 2
    I'm not sure there is a good way to visualize `merge` command on that diagram. By the way, any ideas why `rebase` is specified like an arrow from the remote repository to the workspace? –  Aug 18 '19 at 18:12
  • @akobbs I’m the newbie. Where do you think rebase should be pointing to? – piccolo Aug 18 '19 at 18:15
  • 1
    I think the diagram tries to explain too much and as a result doesn’t do it well. – evolutionxbox Aug 18 '19 at 19:18
  • @akobbs probably a pull merge vs a pull rebase (which can easily be confusing, because git rebase is related but more powerful). To the OP: “git is not GitHub” is a good lesson to learn early. Try to keep GitHub in your head as “one spot to have remotes” and not “git”—it will help. – D. Ben Knoble Aug 19 '19 at 02:59
  • You had selected the right answer before. The file in a workspace are (almost) *always* involved in a merge. See my [edited answer below](https://stackoverflow.com/a/57547452/6309). – VonC Aug 19 '19 at 07:46

3 Answers3

4

As I commented, "rebase" here is in the context of a git pull --rebase:

  • fetch from the remote repository
  • rebase on top of the remote tracking branch which just got updated by the fetch.

A git merge would be between local repository and workspace:

  • local repository has the source of the merge: what you are merging from,
  • workspace is your working tree, where you have checked out your current working branch: it is what you want to merge to.

You need a workspace in order to resolve possible merge conflicts.

While Schwern's answer is technically correct, it is confusing.

  • yes, there are some edge cases (as seen here or there) where you could merge without involving a working tree.
  • but a working tree is (almost always) involved when merging

The intent of the diagram is to show you where to look after a git command execution.

From "True Merge"

A merged version reconciling the changes from all branches to be merged is committed, and your HEAD, index, and working tree are updated to it.
It is possible to have modifications in the working tree as long as they do not overlap; the update will preserve them.

If you were to do a git merge in a bare repository (no working tree), you would get:

fatal: this operation must be run in a work tree

(From setup.c#setup_work_tree())

See also:

https://appendtonew.wpengine.com/wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-8.37.13-PM-1024x663.png

(Source: www.patrickzahnd.ch)

For a more interactive visual Git cheatsheet: an interaction from NDP Software, from Andrew Peterson:

cheatsheet


Don't forget that with Git 2.23 (released yesterday), you have two new (experimental) commands: git switch and git restore.
They could clarify what git checkout was doing before.

VonC
  • 1,042,979
  • 435
  • 3,649
  • 4,283
  • This is a good answer. Funny that I end up with exactly the same one – Philippe Aug 18 '19 at 19:11
  • @Philippe Yes, I have always known a merge needing a workspace, which makes sense when you have conflicts to resolve. – VonC Aug 18 '19 at 19:18
  • To be clearer, you don't merge to the workspace in the same way you merge from the local repo. The merge happens between two commits within the local repo and the result is copied to the workspace. – Schwern Aug 18 '19 at 20:56
  • 1
    @Schwern Interesting distinction. I have upvoted your answer. I would maintain my (simplified) vision of git merge, but I understand your answer. – VonC Aug 18 '19 at 21:34
  • @VonC Thank you, I wanted to expand on yours. I've taken to interpreting the diagram as what parts each command affects and how those changes flow. The merge happens in the local repo and flows to the workspace. [I've taken a stab at this in the past](https://www.dropbox.com/s/lssjbfkfvp7r4q0/Git%20Cheat%20Sheets.pdf?dl=0) and don't yet have a good way to merge the workspace/index/repo flow (page 1) with the commit graph (page 2). – Schwern Aug 18 '19 at 21:44
2

git merge is between two commits in your local repository to make a new commit; this cannot be expressed in the diagram. That new commit is then checked out into your working tree. If there's a conflict that is also checked out into your working tree for you to fix and commit.

The important distinction that might be lost in this diagram is the content of your workspace is not involved in the merge. git merge master is between the commit pointed at by master and the commit pointed at by HEAD (your currently checked out commit). The files in your workspace are not involved.

A more complete diagram of how changes flow would look like this.

| commit -a (add + commit) =======================> |
| add/rm =================> | commit =============> |
|                           | <==== reset -- <path> |
|                           |                       | push =======> |
|                           |                       |               |
workspace                   index                   local           remote
|                           |                       |               |
| <=========================================== pull (fetch + merge) |
|                                                   | <====== fetch |
| <========================================= rebase |
| <========================================== merge |
| <================================= checkout <rev> |
| <===== checkout -- <path> |
| <======================= checkout <rev> -- <path> |
| ========== diff ========= |
|                           | === diff --staged === |
| ============== diff <rev> ======================= |

Notes

  • <rev> is a revision like a commit id, branch name, or tag.
  • The "index" is better named the "staging area", it's where you build up (stage) a commit.
  • Both add and rm write to the staging area.
  • Because some Git commands take both a revision and a path, -- says what follows is unambiguously a path.
  • git reset -- <path> can be thought of as "unstage".
  • git diff shows what is changed but not staged.
  • git diff --staged shows what you're about to commit.
  • A pull is a fetch and then a merge (or rebase with git pull --rebase).
  • Git doesn't speak to the remote unless you tell it to.
  • checkout is a mess. The latest version of Git splits it into switch and restore.
Schwern
  • 127,817
  • 21
  • 150
  • 290
  • I took the liberty to dissent from your interpretation, and have edited my answer. – VonC Aug 19 '19 at 16:34
  • @VonC I don't think we disagree. The merge happens between two commits within the local repo and the result is copied to the workspace. In this diagram that means the merge goes between local and workspace. Git might require the workspace, I'm not saying it doesn't, but that's probably so there's somewhere to resolve the conflicts. The important clarification is when you do `git merge branch` it's merging what's in `branch` and `HEAD`, not `branch` and the workspace. It avoids people wondering why their uncommitted changes weren't merged. – Schwern Aug 19 '19 at 16:47
1

I think that there is an error in the diagram and it's pull or pull --rebase that should be written.

rebase or merge,if that make sense to be displayed in this diagram (I don't think it helps to do it) , that would be between 'local repository' and 'workspace'.

Because you merge or rebase references (remote or local) that are already present in your local repository. And the updated reference/branch is the currently checked out one, so that update also the 'workspace'.

I hope it helps a little but don't give it too much importance because I'm not sure it will helps you to understand how the merge command works.

Philippe
  • 21,230
  • 5
  • 41
  • 62