palazzo train
palazzo train

Reputation: 3409

Skip copying some branches/tags to local Git with `git fetch --all`

I have many remotes added to my Git. Each remote is a repository for one developer. Every day I fetch --all to see any new branches they create that are ready to review.

However, developers can push "private" branches to the remote. Say, all branches named with an underscore prefix are not ready to review, while other branches are ready to review.

When doing the git fetch --all, my Git graph (by /libexec/git-core/git-gui) will see all branches, no matter whether they have the underscore prefix or not. It complicates the graph.

I want git fetch to ignore those _XXXX branches from being downloaded to my local Git. So when I view the Git graph it's like:

How can I do this?

Upvotes: 14

Views: 10285

Answers (4)

Michael come lately
Michael come lately

Reputation: 9382

Update for Git v2.29.0

With negative refspecs,1 added in Git v2.29, you can achieve your original intent without any changes to your coworkers’ habits.

For each coworker’s remote, add a negative refspec (i.e. prefixed with ^) to exclude the _-prefixed branches. This is loosely adapted from the unit test for .git/config and the one for negative patterns. See the last line in the code block below for "Fred’s" remote.

[remote "fred"]
    url = something.git
    fetch = +refs/heads/*:refs/remotes/fred/*
    fetch = ^refs/heads/_*

You have two options to set this for fred on the command line:

  • git config --add remote.fred.fetch '^refs/heads/_*'
  • git remote set-branches --add fred '^refs/heads/_*'

Original answer

Expanding on VonC's excellent answer with a special "review" folder,2 you can modify your .git/config’s entries for your coworkers’ remotes. Here is the relevant documentation.

Where it was once

[remote "fred"]
    url = something.git
    fetch = +refs/heads/*:refs/remotes/fred/*

You can change it to

[remote "fred"]
    url = something.git
    fetch = +refs/heads/review/*:refs/remotes/fred/review/*
    fetch = +refs/heads/other_pattern/*:refs/remotes/fred/other_pattern/*
    fetch = +refs/heads/specific_branch:refs/remotes/fred/specific_branch

After doing so, you may have to clean up the references to refs you have already fetched, but future git fetch --alls or git fetch freds will not update anything outside of the patterns you specified.


1 The documentation on negative refspecs is kind of minimal and buried in a longer passage, so the best place to look is in Git's history or in VonC's answer to a different question, where he pulls the relevant parts together.
2 Or as many special or interesting folders and branches as you need.

Upvotes: 22

SzG
SzG

Reputation: 12629

You could do it in one step with an alias. Add this to your ~/.gitconfig file:

[alias]
    fall = !sh -c 'git fetch --all && git branch -r | sed /HEAD/d | grep /_ | xargs git branch -dr' --

And then just say git fall. It will delete all remote branches that contain /_.

You can observe the intricacies of aliases that are shell commands.

Upvotes: 2

Dinesh
Dinesh

Reputation: 1

You could use the ignore-refs option:

git fetch --ignore-refs branch123

Upvotes: -4

VonC
VonC

Reputation: 1326706

Instead of using a '_' naming convention, you could use namespaces, pushing the branch in origin/review/Branch1 (git push Branch1:review/Branch1)
(named "group" in that answer, or "hierarchical branch name (branch names with slash) in that answer)

That way, you only have to fetch what is in the "review' namespace:

git fetch +refs/heads/review/*:refs/remotes/origin/review/*

The only other option would be a script, which would:

Upvotes: 6

Related Questions