15

How to find all changed files since last commited build in GIT ? I want to build not only the changed files at head revision but also, all the changed files which got changed before that as well since last successful build.

git show --pretty="format:" --name-only will do the build only for top commit changed files. Like this, i need to build for all changed files in different commits since last successful build.

Like , last build done in Jenkins at X SHA-1 id, and after that , there are 3 more commits on top of it. So, my aim is to checkout whole repository codebase till head and then find out list of all files which got changed after X SHA-1 id , that are 3 commits on top of last commit at X SHA-1 id ?

Thanks

user2571169
  • 181
  • 1
  • 1
  • 4

5 Answers5

25

Little late to the party but a slightly better way is to use the --name-only functionality on git diff. What I used is as follows:

git diff --name-only $GIT_PREVIOUS_COMMIT $GIT_COMMIT

This way you don't have to do some piping work afterward.

ford prefect
  • 7,096
  • 11
  • 56
  • 83
  • +1 for a short answer but I am not quite sure why $GIT_PREVIOUS_COMMIT gives me revision number same as GIT_COMMIT revision. Would you know why? – skyrocker Sep 26 '17 at 00:22
  • My guess is that this is an artifact of current state of the repository more than anything else. – ford prefect Sep 26 '17 at 13:19
7

According to https://wiki.jenkins-ci.org/display/JENKINS/Git+Plugin#GitPlugin-Environmentvariables, Jenkins provides the environment variables:

  • GIT_COMMIT - SHA of the current
  • GIT_PREVIOUS_COMMIT - SHA of the previous built commit from the same branch (the current SHA on first build in branch)

I plan to leverage those to accomplish something similar.

So what you'll want is something like:

tar cvzf /tmp/build.tar.gz `git diff --stat $GIT_PREVIOUS_COMMIT $GIT_COMMIT | grep '\|' | awk '{print $1}'`
Telmo Pimentel Mota
  • 4,033
  • 16
  • 22
Ian
  • 86
  • 1
  • 5
4

I'm not entirely sure I follow your question, but two things to consider:

  • git diff --stat {X SHA-1 ID} should work for what you're looking for. Or, you could be more explicit and do git diff --stat {X SHA-1 ID} {X SHA-1 ID + 3 commits} which will give you the files changes between the two commits given. This will output something like:

    Library/ENV/4.3/cc                |  3 ++-
    Library/Formula/cmu-sphinxbase.rb | 10 +++++++---
    Library/Formula/fb-client.rb      | 11 +++++++++++
    

    I leave it as an exercise for the reader to parse that output into just a list of files.

  • You should probably be doing a full, clean build in Jenkins, and not only building certain files. You may end up getting caught by weird incompatibilities between built files. But that's beyond the scope of this question.

---Edit with more info---

To break this problem down into parts:

  1. Get SHA1 hashes to work with - You need the current HEAD of repo (Checking out Revision, which we will call $CUR_HASH) and commit when Jenkins last built (Last Build Revision, which we will call $LAST_HASH). It sounds like you already have these, and if not, that's sort of beyond the scope of the question.
  2. Get list of files changed between $LAST_HASH and $CUR_HASH - This is the aforementioned git diff --stat $LAST_HASH $CUR_HASH command, which will print out something like the above.
  3. Get just the filenames from the output - doing this in bash, you could pipe the output of git diff to grep '\|' to get just the lines with filenames, and then pipe it to awk '{print $1} to get just the filename, without the stats. So the command is now something like:

    git diff --stat $LAST_HASH $CUR_HASH | grep '\|' | awk '{print $1}'
    
  4. Create tarball from just the files changed - you can send the output of the above to tar like so:

    tar cvzf /tmp/build.tar.gz `git diff --stat $LAST_HASH $CUR_HASH | grep '\|' | awk '{print $1}'`
    

I think that covers everything that you're trying to do. Obviously, these commands can't just be copy/pasted since I don't know everything about your environment, but it's a good start.

Xiian
  • 101
  • 3
  • Let me rephrase my question once. Jenkins build the code. It first shows last build revision at some particular SHA-1 id and then it checked out the latest code of head at Z SHA-1 id. What I am looking for is to create a tar file of all changed files only which got changed at latest check out i.e after last successful jenkins build at revision X SHA-1 ( Last Built Revision: ) id and current latest head SHA-1 id ( Checking out Revision ). – user2571169 Jul 31 '13 at 20:19
  • Xiian, any thoughts on this pls ? – user2571169 Jul 31 '13 at 21:05
  • Thanks. But unfortunately, I don't have any values for $LAST_HASH $CUR_HASH as part of Jenkins build. What my objective is whenever we trigger any new build in Jenkins, it should always create a tar for all changed files between $LAST_HASH $CUR_HASH. Can you please suggest how can I substitute these values of $LAST_HASH $CUR_HASH always in Jenkins during build process and will get the desired tar as output in the end? Thanks. – user2571169 Aug 01 '13 at 05:10
1

Maybe this is what you are looking for:

git whatchanged origin/master -n 1

This will tell you all changed files since last commited build.

To know more about git-whatchanged command: https://git-scm.com/docs/git-whatchanged/1.8.3

Also, if you want to know the changes of previous commit only, the modified command is:

git whatchanged -n 1

Hope this help.

Yatharth7
  • 135
  • 1
  • 10
0

If you need this for Jenkins.

prev_merge=$(git log |grep -C1 Merge | grep commit |head -n1 | awk {'print $2'})
commit=$(git log |head -n 1  | awk {'print $2'})
git diff --name-only $prev_merge $commit
Ahmed
  • 2,825
  • 1
  • 25
  • 39
  • I notice that this is showing the commits for master, is there a way to run this for a particular branch? I am triggering Jenkins from a push to branch, and I wish to use the above to grab the files which have been changed in a single commit to the target branch. – fuzzi Mar 04 '19 at 16:58