git: list of all changed files including those in submodules

前端 未结 6 1695
死守一世寂寞
死守一世寂寞 2020-12-08 02:53

I would like to get a list of all files, which have changed betweet two commits including those in submodules.

I know I can do this:

git diff --name-         


        
相关标签:
6条回答
  • 2020-12-08 03:07

    So, the very straightforward script that lists all changes compared to a revision

    #!/bin/sh
    echo "Listing changes for super module"
    git diff $1 --name-only
    subs=(`git submodule | awk '{print $2}'`)
    for sub in ${subs[*]}; do
       lastrevision=`git diff  $1 $sub | fgrep "Subproject" | head -n1 | awk '{print $3}'`
       cd $sub
       echo "Listing changes for $sub"
       git diff $lastrevision --name-only
       cd ..
    done
    

    it takes one argument - revision you want to compare with. Make sure that there is fgrep "Subproject", not fgrep "Submodule".

    0 讨论(0)
  • 2020-12-08 03:14

    You can find out what version a submodule was at, as of a given parent module commit, using git ls-tree:

    subcommit=$(git ls-tree $parentcommit $submodulepath | awk '{print $3}')
    

    So here's a script that should get you much of the way there, up to output formatting and such:

    #!/bin/sh
    
    function compare {
        if [[ -z "$3" ]];
            then git diff --name-only --ignore-submodules=all --diff-filter=ACMR "$1" "$2"
            else git diff --name-only --ignore-submodules=all --diff-filter=ACMR "$1" "$2" | awk -v r=$3 '{ print "" r "/" $0}'
        fi
    
        for submodule in `git submodule | awk '{print $2}'`
        do
            old=$(git ls-tree $1 $submodule | awk '{print $3}')
            new=$(git ls-tree $2 $submodule | awk '{print $3}')
            (cd $submodule; compare $old $new $submodule)
        done
    }
    
    compare "$1" "$2"
    

    This will output all files like this (although Base is a submodule): HtmlTemplates/Css/Screen.css Base/Php/Classes/Helper.php

    0 讨论(0)
  • 2020-12-08 03:19

    Update 2017: as I mentioned in "see diff of commit on submodule in gitlab",

    • Git 2.11 (Nov. 2016) introduces

      git diff --submodule=diff
      
    • Git 2.14 (Q3 2017) will improve that by recursing into nested submodules.
      See commit 5a52214 (04 May 2017) by Stefan Beller (stefanbeller).
      (Merged by Junio C Hamano -- gitster -- in commit a531ecf, 29 May 2017)


    Original 2012 answer (pre 2017 Git 2.14)

    Maybe a simple line would be enough:

    git submodule foreach --recursive git diff --name-status
    

    That would actually list files in submodules within submodules.
    (The --recursive option comes from git1.7.3+)

    0 讨论(0)
  • 2020-12-08 03:23

    You can use

    git -c color.diff=false diff --submodule=diff HEAD~1 HEAD | sed -n -e s/^diff\ --git\ a\\///p
    

    to just have a list of your files (with HEAD~1 and HEAD as example refs).

    I prefer

    git -c color.diff=false diff --submodule=diff HEAD~1 HEAD | grep -E "^(diff|Submodule)\ "
    

    to group the files by submodules. Depending on the terminal, it can be important to use the "--no-pager" option, as shown in the following remark.

    Remark: I like the complete colored diffs in a file, which can be "htmlized" for presentation afterwards:

    git -c color.diff=always --no-pager diff --submodule=diff HEAD~1 HEAD > diffFileName
    
    0 讨论(0)
  • 2020-12-08 03:26

    A Windows variant of https://stackoverflow.com/a/13169898/5438298 by Jamey Sharp would be

    @echo off
    if NOT %1.==. goto has_rev1
    
    @echo git diff --name-only including submodules
    @echo usage:
    @echo ^ ^ %~n0 ^<revision1^> [^<revision2^>^|HEAD]
    @exit /b 1
    
    :has_rev1
    setlocal
    set rev1=%1
    if %2.==. (set rev2=HEAD) else (set rev2=%2)
    
    call :show_diff %rev1% %rev2%
    exit /b
    ::eof
    
    :show_diff
    setlocal ENABLEDELAYEDEXPANSION
    for /f "tokens=*" %%l in ('git --no-pager diff --name-only --ignore-submodules^=all --line-prefix^=%3 %1 %2') do set fwds=%%l & set bcks=!fwds:/=\! & echo !bcks! 
    endlocal
    ::git submodule is too slow for this
    ::for /f "tokens=2" %%d in ('git submodule') do call :subm %1 %2 %%d %3
    if exist .gitmodules for /f "tokens=1,3*" %%p in (.gitmodules) do if %%p.==path. call :subm %1 %2 %%q %3
    exit /b
    ::show_diff
    
    :subm
    setlocal
    for /f "tokens=3" %%r in ('git ls-tree %1 %3') do set rev1=%%r
    for /f "tokens=3" %%r in ('git ls-tree %2 %3') do set rev2=%%r
    
    set fwdslash=%3
    set bckslash=%fwdslash:/=\%
    
    pushd %bckslash%
    call :show_diff %rev1% %rev2% %4%bckslash%\
    popd
    
    endlocal
    exit /b
    ::subm
    

    (note that it might need a few more double quotes for spaces in the submodule names to work).

    0 讨论(0)
  • 2020-12-08 03:28

    July 8,2017

    Now to get a diff including that of a submodule, you can use the command -

    git diff --submodule=diff
    

    Note - This has been introduced with Git 2.14.0

    "git diff --submodule=diff" now recurses into nested submodules.

    0 讨论(0)
提交回复
热议问题