How to know if git repository has changes that have not been synchronized with server (origin)?

前端 未结 4 2021
暗喜
暗喜 2021-01-02 01:55

I have a large number of projects setup in Git that were previously managed in CVS. Tortoise CVS as well as Eclipse both made it very easy to see (via icon overlays) if I ha

相关标签:
4条回答
  • 2021-01-02 02:29

    Yesterday I tried to roll my own solution. Here's what I came up with (for a single repository):

    #!/bin/sh
    
    for ref in $(git for-each-ref --format='%(refname)' refs/remotes/); do
        ending=${ref#refs/remotes/}
        remote=${ending%/*}
        branch=${ending#*/}
        if [ "${branch}" == "HEAD" ]; then continue; fi
        echo -e "\e[1;34m$branch on $remote\e[0m"
        echo "AHEAD by:"
        git log --oneline $branch ^$remote/$branch
        echo "BEHIND by:"
        git log --oneline $remote/$branch ^$branch
    done
    

    This was based off info I've pulled several sources including answers here. I'm still a bit shady on what the 'git log' command is doing given the parameters I'm providing -- but it seems to spit out the kind of info I want.

    0 讨论(0)
  • 2021-01-02 02:30

    If you have a remote named, say, origin, - try running this:

    git remote show origin
    

    This will give you a nice summary.

    For example this is what I get

    git % git remote show origin
    * remote origin
      Fetch URL: git://git.kernel.org/pub/scm/git/git.git
      Push  URL: git://git.kernel.org/pub/scm/git/git.git
      HEAD branch: master
      Remote branches:
        html   tracked
        maint  tracked
        man    tracked
        master tracked
        next   tracked
        pu     tracked
        todo   tracked
      Local branches configured for 'git pull':
        html   merges with remote html
        master merges with remote master
      Local refs configured for 'git push':
        html   pushes to html   (local out of date)
        master pushes to master (local out of date)
    

    which shows that my local branches html and master are out of date. If my remote had commits that were not in my local repo - it would show in the section of branches configured for git pull.

    replace origin with the name of any remote repository.

    If you don't know what the names of your origins are, or their URLs try this:

    git remote -v
    

    which will give you a list of your remotes and their URLs.

    Edited to add

    If you have many submodule you could use git submodule foreach as I've described here. You could redirect the output and parse it to get what you need.

    0 讨论(0)
  • 2021-01-02 02:44

    The following examples only deal with a single repository. Use a loop in a surrounding script to run them on multiple repositories.

    You will probably want to run (e.g.) git fetch origin to update your local remote-tracking branches before using the following commands (so that you are checking against the most up-to-date tips of the upstream branches).

    If you are only concerned with the branch that is currently checked out:

    git status -sb
    

    If the first line reports “ahead”, then the current branch has commits that are not part of its upstream branch. The output of this command is not suitable for consumption directly by a program (it is a “porcelain” command). For programatic consumption use a “plumbing” command to list the “ahead” commits:

    git rev-list HEAD@{upstream}..HEAD
    

    You can pipe that to wc -l to get a count. If you are only interested in the “ahead” status (not the exact count), then test -n "$(git rev-list -n 1 HEAD@{upstream}..HEAD)" may be faster.

    If you want to check on all the branches of a repository:

    git branch -v
    

    Again, you will see “ahead” for branches with commits that are not part of their upstream branch. This is also a “porcelain” command, so if you want to reliably detect the state in a program, then you will want to use some “plumbing” commands:

    git for-each-ref --shell --format='
        b=%(refname:short)
        u=${b}'@{upstream}'
        if git rev-parse --verify --quiet "$u" >/dev/null 2>&1; then
            test -n "$(git rev-list -n 1 "$u..$b")" &&
            echo "$b: has unpushed commits"
        else
            echo "$b: no upstream configuration" >&2
        fi
    ' refs/heads | sh
    

    Adjust the echo statements (or replace them with other commands) to suit your purposes.

    0 讨论(0)
  • 2021-01-02 02:47

    Something like git log origin/master..master should give you the commits that you have done and not pushed. If you fetch origin and then do git log master..origin/master you can see commits in remote master. You can also do git log origin/master...master to see new commits both locally and remote.

    You can replace git log with git rev-list and easily figure out if and what is not pushed in a script if needed.

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