Git Product home page Git Product logo

multi-git-status's Introduction

mgitstatus

Show uncommitted, untracked and unpushed changes in multiple Git repositories. Scan for .git dirs up to DEPTH directories deep. The default is 2. If DEPTH is 0, the scan is infinitely deep.

mgitstatus shows:

  • Uncommitted changes if there are unstaged or uncommitted changes on the checked out branch.
  • Untracked files if there are untracked files which are not ignored.
  • Needs push (BRANCH) if the branch is tracking a (remote) branch which is behind.
  • Needs upstream (BRANCH) if a branch does not have a local or remote upstream branch configured. Changes in the branch may otherwise never be pushed or merged.
  • Needs pull (BRANCH) if the branch is tracking a (remote) branch which is ahead. This requires that the local git repo already knows about the remote changes (i.e. you've done a fetch), or that you specify the -f option. mgitstatus does NOT contact the remote by default.
  • X stashes if there are stashes.

Since there are a lot of different states a git repository can be in, mgitstatus makes no guarantees that all states are taken into account.

mgitstatus can also list dirs that are not a repo, if given the -w switch. To ignore certain repos, set the mgitstatus.ignore git config flag for that repo to true. (See "usage" below for an example).

Usage

Usage: mgitstatus [--version] [-w] [-e] [-f] [--throttle SEC] [-c] [-d/--depth=2] [--no-depth] [--flatten] [--no-X] [DIR [DIR]...]

mgitstatus shows uncommitted, untracked and unpushed changes in multiple Git
repositories. By default, mgitstatus scans two directories deep. This can be
changed with the -d (--depth) option.  If DEPTH is 0, the scan is infinitely
deep.

  --version        Show version
  -w               Warn about dirs that are not Git repositories
  -e               Exclude repos that are 'ok'
  -f               Do a 'git fetch' on each repo (slow for many repos)
  --throttle SEC   Wait SEC seconds between each 'git fetch' (-f option)
  -c               Force color output (preserve colors when using pipes)
  -d, --depth=2    Scan this many directories deep
  --no-depth       Do not recurse into directories (incompatible with -d)
  --flatten        Show only one status per line

You can limit output with the following options:

  --no-push
  --no-pull
  --no-upstream
  --no-uncommitted
  --no-untracked
  --no-stashes
  --no-ok          (same as -e)

The following example scans all directories under the current dir, with a depth of 2. That means the current dir and all directories directly under it.

~/Projects/fboender $ mgitstatus
./mgitstatus: ok
./mdpreview: ok
./snippets: ok
./boxes: ok
./ansible-cmdb: Uncommitted changes Untracked files
./scriptform: Uncommitted changes

For more examples, see the manual page.

Installation

mgitstatus requires make.

The following steps will install mgitstatus:

# Clone the repo
$ git clone https://github.com/fboender/multi-git-status.git
$ cd multi-git-status

# Install globally (all users)
$ sudo make install

# Install locally (only your user)
$ PREFIX=~/.local make install

License

Copyright 2016-2022, Ferry Boender (et al).

Licensed under the MIT license. For more information, see the LICENSE.txt file.

multi-git-status's People

Contributors

bexelbie avatar bradym avatar fboender avatar lyknode avatar rolfkleef avatar ssimmen avatar supersandro2000 avatar vst avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

multi-git-status's Issues

Can we get a new release?

This act will trigger a bunch of distributions to update. Without it, distributions need to switch to git hashes instead of versions.

branches in .git/logs/refs/heads are not checked, but do show up as branches in git-branch

I have an (old) git repo that has a branch that is not in .git/refs/heads but in .git/logs/refs/heads. It shows up as a normal branch in git branch and also when doing git for-each-ref --format '%(refname:short)' refs/heads/. Maybe we should replace the for REF_HEAD in $(cd $GIT_DIR/refs/heads with the git for-each-ref command? (I'd be happy to provide a PR)

"backing up" a git tree

I started writing a patch and then abandoned it to add a feature that would provide the clone and repo commands required to duplicate a git directory tree.

Is this of interest? It feels tangentially related at best but would be useful for me, at least.

I could even imagine a hybrid mode where the output is (theoretically) a list of directories with uncommitted work that should be backed up as files and a list of git commands that will recreate all other repos in their correct location with their correct remotes.

WDYT?

Suggestions to improve packaging of mgitstatus

Hi @fboender,

First and foremost, thank you for mgitstatus. This tool saved me countless times from writing a quick and dirty for loop in bash, while having a nice output and expected options.

To share the awesomeness of this tool, I intend to package it for Debian. It should be available in the next stable release for users to install with apt install mgitstatus.

As such, I would like to suggest a couple of changes that could improve the easiness of packaging of mgitstatus. I'm happy to provide you with the corresponding PRs but I would like to discuss each point with you first.

Suggestions

1. Build system

I'd suggest to use a Makefile for the build system. Easy to use, and fairly easy to maintain for a small project, it would allow users to test and install with:

make #for the manpage
make test #for shellcheck
sudo make install

With the combination of DESTDIR and PREFIX, it would install by default in /usr/local and allow packaging tools to install in the correct tree.

This would replace build.sla and install.sh

2. Generated files

In Debian, generated files are quite tricky to deal within the source. The simple explanation is that if one cannot reproduce the file bit by bit from the source, it means that the generated files has no source and therefor is not open source.

The issue in mgitstatus is for the manpage mgitstatus.1. That file is obviously generated from mgitstatus.1.md but depending on the system you generate it from, the output will change (for instance, just from the pandoc version).

To deal with that, mgitstatus.1 would need to be removed and generated, at build time, by users (using make).

Now, I know that this suggestion can put off some maintainers due to the additional build dependency (here, pandoc), so I don't have my hopes up. We have ways to deal with that in Debian so it's really up to you whether you want to address this issue or not.

3. Release authentication

I would suggest to make available a cryptographic signature (using GPG keys) of your release tarball. By publishing the signature along side the source tarballs, you ensure that any modification by a third party will be detected by end-users.


All of those are suggestions, and as I've said, I'll be happy to provide PRs if
you are interested by those evolution.

If you have any questions regarding the packaging of mgitstatus for Debian do not hesitate to ask.

Looking forward to your comments,

Shows repo Ok when repo needs pull

Is this an issue with git in general or just the way git runs on my computer?

~/repo/nagios: ok

09:01 $ git status
On branch master
Your branch is behind 'origin/master' by 3 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)

nothing to commit, working tree clean
✔ ~/repo/nagios [master ↓·3|✔]

09:01 $ repostat
~/repo/nagios: Needs pull (master) 

Very nice tool; thanks

Thanks Ferry for this tool. Very nice.

I was using another ones (mine then one found in a gist) but yours is the fastest and the given output is really intuitive. Many thanks for command line arguments like -e, great!

flag remote branches that are ahead of remote master

It would be nice if I could set a flag to report when a remote branch is ahead of remote master. This tells me when my release branches have a bugfix that I have forgotten to merge into my main development branch.

A "no" depth option

Thank you for mgitstatus Ferry.

Could you consider a "no depth" option? Beneficial when passing all repository names that the user wants to check.

Furthermore, there are use cases when the user may get noise even from -d 1 and the user would like "no depth." My recent use case:

  • a development environment-only workspace repo (not producing any code/software itself): camigo-workspace. It exists to speed up code navigation & make it easier to run (Rust) compile checks/tests for multiple related "neighbor" repos.
  • that workspace repo has symlinks to the "neighbor" repos, like camigo -> ../camigo.
  • when I run mgitstatus -e -d 1 camigo*, it reports the same repositories twice (once under the current directory, and once as symlinked through my workspace repo).

Thank you in advance for considering.

UPDATE: I've realized that I could run mgitstatus -e camigo-workspace. But that works only in this instance (because all other repos that I'm interested in are symlinked from under camigo-workspace/). So that is not a general solution.

Question - Refresh the index, or we might get wrong results.

Hi, Thanks for creating this script. It looks really useful.

I am considering using it for my own project folder before I update my operating system. A kind of indication of any repos that are in an untidy state.

However I notice the line:

# Refresh the index, or we might get wrong results.
    git --work-tree "$(dirname "$GIT_DIR")" --git-dir "$GIT_DIR" update-index -q --refresh >/dev/null 2>&1

I am not sure how this changes the state of the repository. Does it add unadded files?

I am not sure if/how it could change the state of a working copy of a repo and whether it is desirable to have such changes happen on a repo.

I am thinking sometimes, a .gitignore file may not have been set correctly and it might add items which were left 'not added'.

I might be wrong, so just want to hear your thoughts on this.

"find: ./.Trash: operation not permitted" appearing when run in home folder

When I run the script in my home folder, I get the following type of output:

find: ./.Trash: Operation not permitted
./repo1: Needs push (main) Uncommitted changes
./repo2: Needs push (master) Uncommitted changes
...

I'm wondering if there's a way to change this behavior so that first line doesn't show up?

"No commits yet" reported as "Uncommitted changes"

To reproduce :

  • Create an empty git repository (git init myemptyrepo)
  • Run mgitstatus on repository
  • Bug : "Uncommitted changes" reported

$ git status

On branch master

No commits yet

nothing to commit (create/copy files and use "git add" to track)

$ mgitstatus myemptyrepo/

myemptyrepo/: Uncommitted changes

Prints `Needs push` while actually needs pull

For repositories that need to update with upstream and don't have any changes in working copy, program show status Needs push, while actually it should be Needs pull.

For example:

screen shot 2016-12-09 at 22 48 08

Obviously I'm not that cool to write ruby core, I just keep it for reference and contemplation.

Add a flag to list branches

Hello, thanks for the wonderful tool.

Would be great if there were a way to list branches other than master/main (regardless of status).

e.g.

mgitstatus --branches

./foo: ok
./bar: my_stale_feature_branch_here

targeting git repos with a nonstandard name/path?

It would be nice to be able to point mgitstatus at nonstandard git repos.

My personal use-case is the yadm dotfile manager https://github.com/TheLocehiliosan/yadm, which is uses a distinct path. Typically we'd just interact with that repo via yadm <git-sub-command>..., but we can also do something like GIT_DIR=~/.yadm/git.repo git status to run plain git commands against it.

I'm not sure what's best in terms of syntax/implementation (I can imagine a few different ways...) but a fairly simple idea is a flag to specify one -name to the find command. For example, I can use something like this to match all of the git repositories mgitstatus finds, plus the yadm repo I mentioned: find -L . -maxdepth 3 -type d -name "*.git" (I had to adjust the maxdepth up 1, though, since that's matching deeper in the tree).

syntax examples out of sync

Aside: Nice script. Glad you recently made a release. I'll probably submit a Nix package for it in the near future.

Entries 2 & 3 in the examples section (homepage & manpage) don't square with the supported syntax or documented synopsis:

$ mgitstatus 3
find: '3': No such file or directory

$ mgitstatus -e --no-stashes 3 /opt/deploy
/nix/store/m6l0dpi6xmgjs1mrsccgq3hv7c9bjx1l-mgitstatus-1.0/bin/mgitstatus: line 102: [: /opt/deploy: integer expression expected
find: Expected a positive decimal integer argument to -maxdepth, but got '/opt/deploy'

FWIW (I realize it's not practical to change the syntax right after you hit 1.0, but just in case it's helpful to have syntax feedback) I think the example syntax with path as the final argument is a little less surprising than the supported syntax.

Fork changes undetected

I created a fork from a repo on GitHub and pulled my version to my machine via Git.
Later, I updated my fork from the original repo via GitHub, and running "multi git status" on my machine said "no changes". However going into the folder of the forked repo, and running "git pull", did find those changes and pull them.

Would it be possible to detect such changes in the future?

Thanks!

Possibility to silence also the "Needs pull" status?

I have plenty of local projects that I work on and whenever I jump into one of them I always do a pull.

To me what I need to get a better overview is what changes that I've done that I have forgotten to share with the rest of my team. Right now I get about 75% "Needs pull" and the rest is "Needs push" or "uncommitted changes" and similar.

What are your thoughts? I'm not the best bash-coder in the world, but I could maybe try and do a PR.

Thanks for a great tool btw!

Not installing (macOS Big Sur)

Both the global option:

install mgitstatus -m 755 /usr/local/bin/
install: -m: No such file or directory

And suggested current user option:

install mgitstatus -m 755 /Users/brayden/.local/bin/
install: -m: No such file or directory

fail on macOS big sur. Shouldn't install have all options before the source?
https://man.openbsd.org/install.1

Swapping the order in Makefile seems to work
install -m 755 mgitstatus /Users/brayden/.local/bin/

Got blocked out of server because queries happened too quickly

This is a fabulous tool, thanks for putting it together.

I have a lot of my git remotes on an ssh server at my workplace. When using the tool on a directory with about 30 repos, it made too many ssh connections too quickly, which triggered the security software on the server, and I got blocked from the server for about 10 minutes. That was fun to diagnose. :)

Is there any way to throttle the tool so that it hits the remote server more slowly?

Thank you!

Thanks for publishing your script! I didn't know how to reach you, so this seemed like an ok via. :P

Repositories under 2 levels deep of a regular folder are not checked

Reproduction

$ mkdir -p a/b/c
$ cd a/; git init foo 
Initialized empty Git repository in /home/ceremcem/.sbin/multi-git-status/a/foo/.git/
$ cd b/; git init bar
Initialized empty Git repository in /home/ceremcem/.sbin/multi-git-status/a/b/bar/.git/
$ cd c; git init baz
Initialized empty Git repository in /home/ceremcem/.sbin/multi-git-status/a/b/c/baz/.git/
$ cd ../../..
$ ./mgitstatus --depth=0 a/
a/b/bar: Uncommitted changes 
a/foo: Uncommitted changes 

Expected

Output should also include the following:

a/b/c/baz: Uncommitted changes 

Conf file to exclude git repositories by certain filters

Hi, great tool! Is it possible to add support for a conf file which contains a list of patterns for repos that should not be checked for git status?

Reason being, I have cloned several git repos over the past time that I wish to keep on my laptop, but I won't be updating them any time. So, I don't want to keep seeing unpushed/unpulled changes for them every time I run mgitstatus.

Of course, one way to do this would be to remove the .git folder from the individual git repos, but I have a lot of them, and doing this for each of them everytime I clone them can be time consuming.

Instead, I would appreciate if mgitstatus would check - on launch - for a conf file, which looks like:

pattern1
pattern2
...

and exclude git repos whose absolute path matches these patterns.

If you're happy to accept such a feature, would you mind me creating a PR for the same?

Wrong status shown when git index is out of date

Sometimes when the git index of a repository is out of date, multi-git-status will show the wrong status:

fboender @ jib ~/Projects/fboender $ mgitstatus . 3
./snippets: Uncommitted changes 
fboender @ jib ~/Projects/fboender $ cd snippets/
fboender @ jib ~/Projects/fboender/snippets (master) $ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
fboender @ jib ~/Projects/fboender/snippets (master) $ cd ..
fboender @ jib ~/Projects/fboender $ mgitstatus . 3
./snippets: ok 

Very slow lately

Even with depth set to 1. What flag should I try? What info should I provide here?
Thanks
Dani

Status is shown as needs push when repo is behind origin.

/puppet: Needs push
~/repo/puppet
$ git status
On branch production
Your branch is behind 'origin/production' by 6 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)

nothing to commit, working tree clean

$ repostat
~/repo/puppet: ok

[Question]/suggestion: Auto add to your path? or dot file?

Just reading through the docs maybe the installation steps could assist noobs (like myself).

Is there a recommended way to install mgitstatus globally?

I was able to do this with just an alias in my ~.bash_profile.
alias mgitstatus='~/<path to parent folder>/multi-git-status/mgitstatus'

But wondering if there was a better way or creating an install script?

p.s. Love the script btw. I did this using a bash command but this way more descriptive and feature-rich 😄

Can we get releases?

I am packing multi-git-status for Fedora. I was wondering if you would consider creating versioned releases?

Install error on M1 macOS Monterey 12.3.1 (21E258)

Output:

~/multi-git-status master
❯ sudo make install
Password:
objc[59119]: Class AppleTypeCRetimerRestoreInfoHelper is implemented in both /usr/lib/libauthinstall.dylib (0x1e2545eb0) and /Library/Apple/System/Library/PrivateFrameworks/MobileDevice.framework/Versions/A/MobileDevice (0x107b744f8). One of the two will be used. Which one is undefined.
objc[59119]: Class AppleTypeCRetimerFirmwareAggregateRequestCreator is implemented in both /usr/lib/libauthinstall.dylib (0x1e2545f00) and /Library/Apple/System/Library/PrivateFrameworks/MobileDevice.framework/Versions/A/MobileDevice (0x107b74548). One of the two will be used. Which one is undefined.
objc[59119]: Class AppleTypeCRetimerFirmwareRequestCreator is implemented in both /usr/lib/libauthinstall.dylib (0x1e2545f50) and /Library/Apple/System/Library/PrivateFrameworks/MobileDevice.framework/Versions/A/MobileDevice (0x107b74598). One of the two will be used. Which one is undefined.
objc[59119]: Class ATCRTRestoreInfoFTABFile is implemented in both /usr/lib/libauthinstall.dylib (0x1e2545fa0) and /Library/Apple/System/Library/PrivateFrameworks/MobileDevice.framework/Versions/A/MobileDevice (0x107b745e8). One of the two will be used. Which one is undefined.
objc[59119]: Class AppleTypeCRetimerFirmwareCopier is implemented in both /usr/lib/libauthinstall.dylib (0x1e2545ff0) and /Library/Apple/System/Library/PrivateFrameworks/MobileDevice.framework/Versions/A/MobileDevice (0x107b74638). One of the two will be used. Which one is undefined.
objc[59119]: Class ATCRTRestoreInfoFTABSubfile is implemented in both /usr/lib/libauthinstall.dylib (0x1e2546040) and /Library/Apple/System/Library/PrivateFrameworks/MobileDevice.framework/Versions/A/MobileDevice (0x107b74688). One of the two will be used. Which one is undefined.
install -d /usr/local/bin
install -d /usr/local/man/man1
install mgitstatus -m 755 /usr/local/bin/
install: -m: No such file or directory
make: *** [install] Error 71

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.