follow a directory which has been renamed?

The git command has a useful command to follow a file after a rename, as in git log --follow path/to/some/file . Unfortunately, it works only for an individual file. I'd like to be able to do the equivalent of git log --follow some/directory .

One way of doing this would probably be to massage the output of git ls-tree and do that in a loop, but the problem then becomes that commits affecting multiple files won't be "coalesced" into one commit.

Is there a better way to do it? Note: using git 2.7.4


No.

Git does not store directories, only files. When you use any path name to commands like git log or git diff that look at entire commits, Git essentially says "start with the whole commit, then shrink it down to file(s) matching that path". Directories here simply wind up selecting every file in the directory.

The --follow option can only follow one file. So if you could somehow manage to get it to apply to a directory, Git would first turn the directory into a set of files, then pick one of those files and follow just that one.

(The actual --follow code is terribly hacky. It leverages off the rename detection code, but only works when commits are being compared in the newer-to-older order: if you add --reverse , --follow never works at all. Probably the whole thing needs to be thrown out and re-coded. Perhaps by re-coding it, you could make it handle multiple file names, and even directories full of files.)


There does not seem to be a builtin way to do this.

One can do this using a script and following a simple algorithm:

  • For each file generate a list of commits associated with it
  • Combine all the lists and do a stable sort on them (this is tricky because determining ordering of commits isn't straightforward)
  • Iteratively execute git log for each of the commits and pipe it all through less
  • Here's a hacky way to do it using python 3 and the sh module, won't work on Windows for various reasons.

    #!/usr/bin/env python3
    
    import os
    import shlex
    import sys
    import tempfile
    
    import sh
    
    def _get_commits(fname):
        # Ask for the commit and the timestamp
        # .. the timestamp doesn't guarantee ordering, but good enough
        for c in sh.git('log', '--follow', '--pretty=%ct %h', fname,
                       _tty_out=False, _iter=True):
            c = c.strip().split()
            yield int(c[0]), c[1]
    
    def git_log_follow_multi(filenames):
        if len(filenames) == 0:
            print("Specify at least one file to log")
        elif len(filenames) <= 1:
            os.system('git log --follow -p %s' % filenames[0])
        else:
            # Use git log to generate lists of commits for each file, sort
            commits = []
            for fname in filenames:
                commits += _get_commits(fname)
    
            # Sort the lists (python's sort is stable)
            commits.sort(reverse=True)
    
            # Uniquify (http://www.peterbe.com/plog/uniqifiers-benchmark)
            seen = set()
            seen_add = seen.add
            commits = [c for c in commits if not (c in seen or seen_add(c))]
    
            # Finally, display them
            tname = None
    
            try:
                file_list = ' '.join(shlex.quote(fname) for fname in filenames)
    
                with tempfile.NamedTemporaryFile(mode='w', delete=False) as fp:
                    tname = fp.name
                    for _, commit in commits:
                        fp.write('git log -p -1 --color %s %sn' % (commit, file_list))
    
                # Use os.system to make our lives easier
                os.system('bash %s | less -FRX' % tname)
            finally:
                if tname:
                    os.unlink(tname)
    
    
    if __name__ == '__main__':
        git_log_follow_multi(sys.argv[1:])
    

    Now, this script doesn't exactly meet your needs since it takes a list of files, but you can execute it using a glob and it'll do what you're looking for.

    ./script.py src/*
    
    链接地址: http://www.djcxy.com/p/92786.html

    上一篇: 由于CPU不足,Pod处于挂起状态

    下一篇: 跟随一个已经重命名的目录?