2

If we git pull and see:

git pull
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint: 
hint:   git config pull.rebase false  # merge (the default strategy)
hint:   git config pull.rebase true   # rebase
hint:   git config pull.ff only       # fast-forward only
hint: 
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
fatal: Need to specify how to reconcile divergent branches.

then we can simply git pull --merge1to merge the remote into the local and see the conflicting files with git diff --name-only --diff-filter=U.

But suppose we wish to see which files conflict before the pull succeeds, that is, before any merge has occurred.

To be very clear, there's changes on the remote, there's changes on my local, and I want to see what the conflicts are before merging the two.

1Sorry, this is wrong, but it's not important. However I'll find the right command and update shortly.

stevec
  • 41,291
  • 27
  • 223
  • 311
  • 2
    Short answer is you can't. Your best shot is to try a merge on a throwaway branch. Might be a duplicate of [Is there a git-merge --dry-run option?](https://stackoverflow.com/questions/501407/is-there-a-git-merge-dry-run-option) or maybe [this one](https://stackoverflow.com/questions/5817579/how-can-i-preview-a-merge-in-git). – Romain Valeri Jan 27 '22 at 09:58
  • @RomainValeri isn't the duplicate previewing a merge between *2 branches* rather than different versions of *the same branch*. I don't see how you could apply the answers in the related question to this scenario, since the answers use `git diff ` but it's the *same* branch. – stevec Jan 27 '22 at 10:12
  • @RomainValeri as in, `git diff main` doesn't mean anything if both branches are called `main`. – stevec Jan 27 '22 at 10:13
  • @RomainValeri (I'm thinking out loud here) or are you implying to i) *create* a branch, ii) `git pull` and merge the changes, *then* iii) use the strategies in the related question to compare the 2 branches? – stevec Jan 27 '22 at 10:14
  • `git diff yourbranch origin/yourbranch` is fine. Even shorter, and branch-name-agnostic : `git diff HEAD @{u}` – Romain Valeri Jan 27 '22 at 10:16
  • @RomainValeri maybe I didn't make clear in the explanation, but the remote is really "remote" (it's on GitHub). It's not `pull`ed yet, so cannot be `diff`ed. – stevec Jan 27 '22 at 10:17
  • @RomainValeri git needs to know about the remote changes. So an answer needs to include how it's going to get them. – stevec Jan 27 '22 at 10:17
  • But it can be *fetched*. Fetch from the remote before diffing the remote-tracking ref you just fetched against your local version. – Romain Valeri Jan 27 '22 at 10:18
  • @RomainValeri when I `fetch` what will the branch be called (if my assumption that it creates a branch is even correct?) – stevec Jan 27 '22 at 10:19
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/241450/discussion-between-romain-valeri-and-stevec). – Romain Valeri Jan 27 '22 at 10:19

2 Answers2

1

I don't think this is a complete answer, but based on advice from @RomainValeri and @torek, here's what I attempted:

First, get the remote changes without trying to merge them as pull does:

git fetch

Now you have the changes on the remote, take a look at them with this:

git diff HEAD @{u}

(note: ^^ this code came from @RomainValeri, I wish I could say I knew what it does - I can confirm that it works and shows the diff)
(Edit from Romain : about the @{u} expression, see this answer.)

Then, if and when you're happy, you can merge like so:

git merge

(note you'll still have to deal with any merge conflicts, but that's another story...)

Romain Valeri
  • 19,645
  • 3
  • 36
  • 61
stevec
  • 41,291
  • 27
  • 223
  • 311
  • 2
    To really see what would be a *conflict*, you must find the merge base between HEAD and its upstream: `git merge-base --all HEAD @{u}` for instance. This will get you a raw hash ID (or more than one for the rare case of multiple merge bases). Assuming you get just 1, `git diff HEAD` shows what you changed, and `git diff @{u}` shows what they changed. There's a short-cut syntax: `git diff @{u}...HEAD` (note THREE dots here) will find a merge base—hopefully, *the* merge base—and diff that against `HEAD`, and `git diff HEAD...@{u}` will find a merge base and diff that against `@{u}` – torek Jan 27 '22 at 11:01
  • 1
    -- and the two diffs will be what you'd get if you ran the two `git diff`s yourself manually. Inspect the set of changed files, and the changes within those changed files, to look for conflicts. – torek Jan 27 '22 at 11:02
  • @torek great to know. Thank you. I am slowing working thorough what each instruction is doing. You're right about the diff not showing the *conflicts* (it only sufficed for me because they were glaring, but in anything other than simple circumstances a git diff probably would not be enough). Also appreciate you showing both the long and shortcut methods. – stevec Jan 27 '22 at 11:07
1

stevec's answer explains how to preview the merge before it occurs, which is a good option.

Another option is to simply perform the merge, and undo it if you do not like the conflicts.

To do this, run git pull as usual. If there should be a conflict and you do not feel like resolving it right now, you can simply run

git merge --abort

(or git rebase --abort if you used git pull --rebase)

and you will be back to the old state of your working directory. Note that this will only work cleanly if you have no uncommitted changes when pulling - but pulling into an unclean working directory is not a good idea anyway, so just commit (or stash) before pulling.

sleske
  • 81,358
  • 34
  • 189
  • 227