简体   繁体   中英

Shouldn't git branch --no-merged list new branches?

We have a large number of central git repositories and use branches to track work on various projects. When a project finishes, we merge to master and push to origin.

When starting a new project, I'd like to list any other current work on that repository, as a heads-up for the developer (eg so they can communicate their release plans). git branch --all --no-merged origin/master seems promising but apparently it only lists branches that have commits. Conceptually, even newly created, "empty" branches state the intention of doing some work, so shouldn't these be listed too?

I suspect that this may be related to the distinction between a branch and a branch head, and while the branch head points to its start point there is nothing to merge. But since merges are explicitly recorded in history (right?) shouldn't it be possible to identify even "empty" branches as unmerged? Can this be done?

An obvious workaround is to force a dummy initial commit in each new branch but I'd like to avoid this if possible. And it seems developers should not have to push their unfinished changes if they don't want to (so I expect most branches in the central repository would remain empty until their project is completed).

Example:

# Alice creates and pushes branch1
git clone $REPO clone1
git checkout -b branch1
git push -u --all
# ...continues development in her local repository...

# Bob wants to know if anybody is working on $REPO
git clone $REPO clone2
git branch --all --no-merged origin/master
# no output - he doesn't realize Alice is working in the same repository

It seems there is no git built-in support for what I want, but with some git plumbing I got the results I was looking for, inspired by Finding a branch point with Git? .

Let me know if these assumptions are not correct...

  • A branch whose head matches its branch point from origin/master (ie. has no commits) should be an empty branch, indicating the intention of doing work.
  • A branch whose best merge point with origin/master matches its head is already fully merged, and can be ignored.
  • Any other case should be a branch with unmerged changes.

Example script that prints the category for all remote branches; if Bob ran this it would tell him refs/remotes/origin/branch1: new branch without any commits :

#! /usr/bin/env bash

# check branches created from and merged to this branch
MASTER=refs/remotes/origin/master

# for each remote branch...
for BRANCH in $(git for-each-ref --format='%(refname)' refs/remotes/); do
    # ...except the $MASTER branch and the current HEAD
    [[ $BRANCH == $MASTER || $BRANCH =~ /HEAD$ ]] && continue

    # get the hash for the head of the branch
    BRANCH_HEAD=$(git show-ref --head --hash $BRANCH)

    # returns the first shared commit among $MASTER and $BRANCH commits
    BRANCH_POINT=$(fgrep -m 1 -f <(git rev-list --first-parent $BRANCH) \
                                 <(git rev-list --first-parent $MASTER))

    # find the best merge point
    BRANCH_MERGE=$(git merge-base $MASTER $BRANCH)

    # determine the type of branch
    if [[ $BRANCH_POINT == $BRANCH_HEAD ]]; then
        echo "$BRANCH: new branch without any commits"
    elif [[ $BRANCH_MERGE == $BRANCH_HEAD ]]; then
        echo "$BRANCH: fully merged into $MASTER"
    else
        echo "$BRANCH: branch with unmerged changes"
    fi
done

No, because there are no unmerged changes in branch1. Therefore "--no-merged" won't list the branch. Once Alice commits and pushes a change, then it will show up.

I am afraid I am with Doug-W on this one. --no-merged refers to a branch which contains a commit (or many) that the current branch does not contain. Since you are branching from master, than not making a follow up commit then all commits that the branch contain are also within master.

Since creating a branch has no concept of when the branch was created, you are losing out on a metric that may be important to you and your company in the future. If you were to make just a single commit once a branch had been created with just a simple "stub" file then you could use the timestamp of this stub commit and the second commits timestamp to know how long a project was parked for before starting.

This also has the added benefit of reporting these branches in your --no-merged command.

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