简体   繁体   中英

How to check the status of all git repositories at once?

Introduction

In order to check the status of git repositores, git status could be issued from the root of a repository.

C:\path\to\git_repositories\git_repo_1>git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working directory clean

If a directory consists of multiple, eg 50 git repositories

C:\path\to\git_repositories>dir

 Directory of C:\path\to\git_repositories

  .ssh
  git_repo_1
  ...
  git_repo_50
   0 File(s)
   51 Dir(s)

Nor

C:\path\to\git_repositories>git status .
fatal: Not a git repository (or any of the parent directories): .git

neither

C:\path\to\git_repositories>git status ./.
fatal: Not a git repository (or any of the parent directories): .git

is able to check the status of all repositories

Question

How to check the status of all git repositories at once?

You could use a for loop that changes into each directory, does git status and then changes back up:

for /f "tokens=*" %a in ('dir /ad /b') do cd %a & git status & cd ..

You need to double the percentages if you use this in a batch file:

for /f "tokens=*" %%a in ('dir /ad /b') do cd %%a & git status & cd ..

Edit:

As suggested by Cupcake, you could do this instead:

for /f "tokens=*" %a in ('dir /ad /b') do git --git-dir=%a/.git --work-tree=%a status

This feels like a more robust and flexible solution (eg you could adapt it more easily to work with a list of paths stored in a text file).

I went with:

find . -name .git -execdir bash -c 'echo -en "\033[1;31m"repo: "\033[1;34m"; basename "`git rev-parse --show-toplevel`"; git status -s' \;

I think it's nicer because treats directories recursively.

Edited to show the name of the repo in a cleaner way.

If you are a kind of a tool-guy, you could use a little helper called RepoZ I wrote recently (and still write).

I answered a quite similar question in more detail here .

Here's a screenshot from the current development stage so hopefully you can see whether it seems helpful to you or not:

回购协议

If you are wondering what that strings like +45 ~403 -88 mean - they are condensed status strings telling you whether there are commits to fetch or push and whether there are added/modified/deleted files locally. More detail on the project site on GitHub

If you have a system that is made up of numerous Git repositories, that is possibly a situation for which the Google repo tool was created: https://code.google.com/archive/p/git-repo/

If you find yourself writing scripts to distribute Git commands over these repositories, you should probably switch to repo .

repo works with an (unfortunately) XML file called the "manifest.xml" which specifies the Git repositories that are in the workspace. For each repo specifies which branch and commit should appear; you can use repo to "pin" the Git repositories to particular versions, or to track heads.

If you have a repo workspace then

$ repo status

then repo will do pretty much what you're asking for: iterate over the Git repos and give you a status.

In bash I found this really nice command (courtesy of https://coderwall.com/wkjagt ) :

find . -maxdepth 1 -mindepth 1 -type d -exec sh -c '(echo {} && cd {} && git status -s && echo)' \;

To make an alias in your bash_profile use the following with escaping to make it work:

alias gs_recursive='find . -maxdepth 1 -mindepth 1 -type d -exec sh -c "echo {}; cd {}; git status -s; echo" \;'

As of 2.34 the for-each-repo command allows running git commands across a list of repos defined in a multi-valued config.

Example config:

[myRepos]
  repo = /full/path/without/expansion/repo1
  repo = ../can/be/relative/repo2
[alias]
  all = for-each-repo --config=myRepos.repo

Then you can run git all status .

Oof... git's design failed.

When I looked up this question, I was reminded of all the examples out there that use cd to jump into repos and then run git commands in there.

You need to use the options --git-dir= and --work-tree=

(Well... that's what I want to say anyway.)

When we use those options --git-dir is the .git directory in the repo and the --work-tree= value is the repo's root directory.

For example

Let's say we are in C:\ , the repo we're interested in is at C:\workspace\foobar

To get it's status without doing barbaric cd manuevers:

git --git-dir=c:\workspace\foobar\.git --work-tree=c:\workspace\foobar\ status

or for the nice short status we all like.

git --git-dir=c:\workspace\foobar\.git --work-tree=c:\workspace\foobar\ status -s

So that's only a little more than double the typing, and we get to use some barely coherent git options.

Now that we know the civilised way...

What's more we haven't lowered ourselves to virtually banging rocks together and typing...

cd c:\workspace\foobar; git status -s

Why would we ever do that.

(seriously though, do the cd . It's very rare to even find a script doing the --git-dir/--work-tree nonsense. It's extremely poor user service and has all the hallmarks of 0% design thought.)

Now let's do reflog... (ok let's not.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM