28

How do I get the list of files that are about to be updated (or were just updated) by git pull so i can parse them and take appropriate action in a script?

The accepted answer to this similar looking question showed me that I can get a list of commits with

git fetch && git log master..origin/master

but this is no good for me because I need a list of files, and my script cannot assume that the branch is master or that the current branch is tracking origin/master.

Through a little experimentation (and @Jonathan's comment), I have found that

git fetch && git diff master origin/master --name-only

is nearly there, but now I need to find a way to get the current branch and what it's tracking so that I can execute something like this (python):

"git fetch && git diff %s %s --stat" % (this_branch, tracked_branch)

I feel like I'm most of the way there, as now I only really need to know how to get the current branch and what it's tracking, but I've given a wider context in the hope that someone knows a much simpler way of solving this (git incoming --files would be nice ;)

Community
  • 1
  • 1
meshy
  • 8,470
  • 9
  • 51
  • 73
  • 3
    For machine consumption, `--name-only` is probably better that `--stat`. Besides not having to strip out the `| 72 ++--` at the end, it won't truncate file names with ellipses. Not sure if that helps you with you actual problem, but I just though I'd point it out. – Jonathan Dec 15 '11 at 15:41
  • It definitely does help, thankyou :) I'll update the question. – meshy Dec 15 '11 at 15:44
  • @Jonathan: For machine consumption, if you want to know diff sizes, you use `--numstat` not `--stat`. – Cascabel Dec 15 '11 at 22:14

2 Answers2

21

Assuming you know the name of the remote (in my examples, origin) then you could simply go:

git fetch && git diff --name-only ..origin

templates/shows/showBase.html
templates/shows/showList.html
templates/shows/showListEntry.htm

Or if you wanted to sort into individual commits, you could use whatchanged:

git fetch && git whatchanged --name-only ..origin

commit fcb1b56d564fe85615ecd6befcd82f6fda5699ae
Author: Grambo <email@email>
Date:   Mon Dec 12 23:36:38 2011 +0000

    Hooked "I've Seen This" button up to "Review Show" dialog

templates/shows/showBase.html
templates/shows/showList.html
templates/shows/showListEntry.htm

commit xasdasdsada......
obmarg
  • 9,369
  • 36
  • 59
  • `git fetch && git diff --name-only ..origin` is exactly what I need :) I'm pretty sure that the remote will always be "origin" regardless of branch because everything gets cloned straight from bitbucket. Thankyou, accepted :) – meshy Dec 15 '11 at 16:09
  • 1
    `whatchanged --name-only` is pretty much equivalent to `log --name-only` (if there's a difference, I don't know it). – Cascabel Dec 15 '11 at 22:13
  • I ran the command as it is, on my local repository, while I am on master branch and master on remote repository is one version ahead. But I get this error - `fatal: ambiguous argument '..origin': unknown revision or path not in the working tree. Use '--' to separate paths from revisions, like this: 'git [...] -- [...]'` – Sandeepan Nath Mar 17 '16 at 11:37
  • 1
    I had to do `git diff --name-only ..origin/master` – Sandeepan Nath Mar 17 '16 at 12:41
  • Also, when the fetch actually happens, it shows some info, in addition to the file name changes. E.g. - `remote: Counting objects: 4, done. remote: Compressing objects: 100% (2/2), done. remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (4/4), done. From b2c98d5..9de3c78 master -> origin/master test/dummy.txt ` – Sandeepan Nath Mar 17 '16 at 12:47
  • @SandeepanNath You can use the `-q` or `--quiet` option of `git fetch` to show only the filenames of the modified files. The command would be `git fetch -q && git diff --name-only ..origin` – vanir Nov 24 '20 at 15:55
  • 1
    With `git fetch -q && git diff --name-only ..origin` I get `fatal: ambiguous argument '..origin': unknown revision or path not in the working tree.` Adding `/master` to `..origin` - which results in `..origin/master` - it works. – Timo Apr 15 '23 at 11:29
  • I also get `fatal: ambiguous argument '..origin': unknown revision or path not in the working tree.` with `git fetch && git diff --name-only ..origin` OR `git fetch && git diff --name-only ..origin/master` – Dylan_Gomes Jul 10 '23 at 20:59
13

A more generic solution than @obmarg's answer is this:

git fetch && git diff --name-only @ @{u}

Here @ is a shortcut for HEAD which in turn is a pointer to your currently checked out branch. @{u} or @{upstream} denotes the tracking branch for HEAD. So no hardcoded assumptions about the current branch (master), the name of the remote (origin) or the name of the tracking branch (origin/master) is necessary.

If you want to do this with another branch, use this:

git fetch && git diff --name-only master master@{u}

The syntax for @{u} is explained in git help revisions, search for upstream.

A.H.
  • 63,967
  • 15
  • 92
  • 126