开发者

Branch descriptions in Git

Is the开发者_StackOverflow社区re a way in Git to have a 'description' for branches?

While I try to use descriptive names, working for a while on a single branch sometimes dampens my memory of why I made some of the other topic branches. I try to use descriptive names for the branches, but I think a 'description' (short note about the purpose of the branch) would be nice.


Git 1.7.9 supports this. From the 1.7.9 release notes:

 * "git branch --edit-description" can be used to add descriptive text
   to explain what a topic branch is about.

You can see that feature introduced back in September 2011, with commits 6f9a332, 739453a3, b7200e8:

struct branch_desc_cb {
  const char *config_name;
  const char *value;
};

--edit-description::

Open an editor and edit the text to explain what the branch is for, to be used by various other commands (e.g. request-pull).

Note that it won't work for a detached HEAD branch.

That description is used by the script request-pull: see commit c016814783, but also git merge --log.

request-pull is a script used to summarizes the changes between two commits to the standard output, and includes the given URL in the generated summary.

[From @AchalDave] Unfortunately, you can't push descriptions since they're stored in your config, making it useless for the sake of documenting branches in a team.


If you do end up using the README, create a git alias modifying git checkout so that your README is displayed every time you switch branches.

For example, add this in ~/.gitconfig, under [alias]

cor = !sh -c 'git checkout $1 && cat README' -

After this, you can run git cor <branch_name> to switch branch and display the README of the branch you're switching to.


Use git branch --edit-description to set or edit a branch description.

Here is a shell function to show branches similar to git branch but with descriptions appended.

# Shows branches with descriptions
function gb() {
  current=$(git rev-parse --abbrev-ref HEAD)
  branches=$(git for-each-ref --format='%(refname)' refs/heads/ | sed 's|refs/heads/||')
  for branch in $branches; do
    desc=$(git config branch.$branch.description)
    if [ $branch == $current ]; then
      branch="* \033[0;32m$branch\033[0m"
     else
       branch="  $branch"
     fi
     echo -e "$branch \033[0;36m$desc\033[0m"
  done
}

Here is what gb looks like, shown here as text in case the image rots:

$ gb
* logging Log order details.  Waiting for clarification from business.
  master 
  sprocket Adding sprockets to the parts list.  Pending QA approval.

And as an image, so you can see the colors:

Branch descriptions in Git


The README suggested by Chris J can work, provided it is setup with a custom merge driver defined in a .gitattribute.
That way, the local version of the README is always preserved during merges.

The "description" for branches is also know as a "comment" associated with that meta data, and it is not supported.

At least, with a README file, you can, for any branch, do a:

$ git show myBranch:README

If your README is at the root directory of your REPO, it will work from any path, since the path used by git show is an absolute one from the top directory of said repo.


There are two popular suggestions here:

  1. git branch --edit-description : We don't like this because you can't push it. Maybe I can remember what the branches I created do, but my team sure can't.
  2. README file pr. branch. This is a pain during merges: Super-prone to merge conflicts and we'll be pulling in README from branches when we merge feature branches. Diffs between branches are also a pain.

We've decided to create an orphan branches-readme branch. Orphan branches are branches with their own separate history - you may know them from Github's gh-pages branches. This orphan branch contains a single README file. It has contents like:

master:
    The default branch
mojolicious:
    Start using Mojolicious
branch-whatever:
    Description of the whatever branch

It is push-able and merge-friendly. View the README from any branch with:

git show branches-readme:README

Disadvantages are that you need to checkout the weird orphan branch when you want to update the README and the README doesn't auto-update as branches get renamed, come or go. That is fine for us, though.

Do it like:

git checkout --orphan branches-readme
# All the files from the old branch are marked for addition - skip that
git reset --hard
# There are no files yet - an empty branch
ls
vi README
# put in contents similar to above
git add README
git commit -m "Initial description of the branches we already have"
git push origin branches-readme
# get all your original files back
git checkout master

Similary, individual team members can also create their own branches-$user orphan branches describing their own private branches if they want to, as long as they don't push them to the team.

With further tooling this could also be integrated with the output of git branch. To that end, perhaps a README.yaml file could be considered instead of a plain README.


git config --global --add alias.about '!describe() { git config branch."$1".description; }; describe'

Command will define a global option alias.about as shell expression. Running git about <branch> in a repository will display branch's description if set.


Here's a git alias that lets you both set and read descriptions on the current branch:

git config --global --add alias.about '!describe() { msg="$1"; git config branch."$(git rev-parse --abbrev-ref HEAD)".description ${msg:+"$msg"}; }; describe'

Usage/examples:

(develop) $ git about
(develop) $ git about message
(develop) $ git about
message
(develop) $ git about "this is a new message"
(develop) $ git about
this is a new message
(develop) $ git checkout -b test_branch
Switched to a new branch 'test_branch'
(test_branch) $ git about
(test_branch) $ git about "this is the test branch"
(test_branch) $ git about
this is the test branch
(test_branch) $ git checkout -
Switched to branch 'develop'
Your branch is up to date with 'origin/develop'.
(develop) $ git about
this is a new message

Special thanks to @Felicio for the answer that got me started.


Here's a possible implementation of the git branches command Greg Hewgill alluded to:

#!/usr/bin/perl

sub clean {
    map { s/^[\s\*]*\s// } @_;
    map { s/\s*$// } @_;
    return @_;
}

sub descr {
    $_ = `git config branch.@_.description`;
    s/\s*$//;
    return $_;
};
sub indent {
    $_ = shift;
    s/^/      /mg;
    return $_;
};

my @branches = clean `git branch --color=never --list`;
my %merged = map { $_ => 1 } clean `git branch --color=never --merged`;

for my $branch (@branches) {
    my $asis = `git branch --list --color=always $branch`;
    $asis =~ s/\s*$//;
    print "  $asis";
    print " \033[33m(merged)\033[0m" if ($merged{$branch} and $branch ne "master");
    print "\n";

    print indent descr $branch;
    print "\n";
    print "\n";
}


Say you want to create a branch

git branch branch-20200328
git notes add branch-20200328 -m "This branch is for whatever"
git notes show branch-20200328


You can attach comments to tags:

git tag -m 'this was a very good commit' tag1

By convention, you could have tags related to your branch names or you could use tag -f to keep a commented tag at the head of your topic branches.


You can use

git config --get-regexp "branch.*.description"


Just use:

git config branch.<branch name>.description

To give credit where credit is due: https://glebbahmutov.com/blog/git-branches-with-descriptions/


I am pretty sure that feature is not currently supported. I think your best bet is to create a description text file, a README basically, in the branch that has the information that you want.


The selected answer seems like overkill to me. I'd be inclined to maintain a per branch description file that is a normal source controlled file, say master.txt, dev.txt, etc. and if there is an unwieldy number or branches I'd create a hierarchy to better organize it.


Regarding Greg Hewgill's 2012 answer, Git 1.7.9 (Q1 2012) also included some checks for git branch --edit-description:

See commit c2d17ba (05 Feb 2012) by Junio C Hamano (gitster).
(Merged by Junio C Hamano -- gitster -- in commit d88698e, 10 Feb 2012)

branch --edit-description: protect against mistyped branch name

It is very easy to mistype the branch name when editing its description, e.g.

$ git checkout -b my-topic master
: work work work
: now we are at a good point to switch working something else
$ git checkout master
: ah, let's write it down before we forget what we were doing
$ git branch --edit-description my-tpoic

The command does not notice that branch 'my-tpoic' does not exist.
It is not lost (it becomes description of an unborn my-tpoic branch), but is not very useful.
So detect such a case and error out to reduce the grief factor from this common mistake.

This incidentally also errors out --edit-description when the HEAD points at an unborn branch (immediately after "init", or "checkout --orphan"), because at that point, you do not even have any commit that is part of your history and there is no point in describing how this particular branch is different from the branch it forked off of, which is the useful bit of information the branch description is designed to capture.

We may want to special case the unborn case later, but that is outside the scope of this patch to prevent more common mistakes before 1.7.9 series gains too much widespread use.


While Greg Hewgill's 2012 answer is accurate, using git branch --edit-description can lead to:

fatal: could not unset 'branch.main.description'

"GIT_EDITOR=: git branch --edit-description(man) resulted in failure, which has been corrected with Git 2.39 (Q4 2022).

See commit e288b3d (30 Sep 2022) by Junio C Hamano (gitster).
(Merged by Junio C Hamano -- gitster -- in commit 272be0d, 17 Oct 2022)

branch: do not fail a no-op --edit-desc

Imagine running "git branch --edit-description"(man) while on a branch without the branch description, and then exit the editor after emptying the edit buffer, which is the way to tell the command that you changed your mind and you do not want the description after all.

The command should just happily oblige, adding no branch description for the current branch, and exit successfully.
But it fails to do so:

$ git init -b main
$ git commit --allow-empty -m commit
$ GIT_EDITOR=: git branch --edit-description
fatal: could not unset 'branch.main.description'

The end result is OK in that the configuration variable does not exist in the resulting repository, but we should do better.
If we know we didn't have a description, and if we are asked not to have a description by the editor, we can just return doing nothing.

This of course introduces TOCTOU.

(Time-of-check to time-of-use (TOCTOU): a class of software bugs caused by a race condition involving the checking of the state of a part of a system (such as a security credential) and the use of the results of that check.)

If you add a branch description to the same branch from another window, while you had the editor open to edit the description, and then exit the editor without writing anything there, we'd end up not removing the description you added in the other window.
But you are fooling yourself in your own repository at that point, and if it hurts, you'd be better off not doing so ;-).


Also: "git branch --edit-description"(man) on an unborn branch misleadingly said that no such branch exists, which has been corrected with Git 2.39 (Q4 2022).

See commit bcfc82b (08 Oct 2022) by Rubén Justo (rjusto).
(Merged by Junio C Hamano -- gitster -- in commit 4050354, 17 Oct 2022)

branch: description for non-existent branch errors

Signed-off-by: Rubén Justo

When the repository does not yet have commits, some errors describe that there is no branch:

$ git init -b first

$ git branch --edit-description first
error: No branch named 'first'.

$ git branch --set-upstream-to=upstream
fatal: branch 'first' does not exist

$ git branch -c second
error: refname refs/heads/first not found
fatal: Branch copy failed

That "first" branch is unborn but to say it doesn't exists is confusing.

Options "-c" (copy) and "-m" (rename) show the same error when the origin branch doesn't exists:

$ git branch -c non-existent-branch second
error: refname refs/heads/non-existent-branch not found
fatal: Branch copy failed

$ git branch -m non-existent-branch second
error: refname refs/heads/non-existent-branch not found
fatal: Branch rename failed

Note that "--edit-description" without an explicit argument is already considering the empty repository circumstance in its error.
Also note that "-m" on the initial branch it is an allowed operation.

Make the error descriptions for those branch operations with unborn or non-existent branches, more informative.

This is the result of the change:

$ git init -b first

$ git branch --edit-description first
error: No commit on branch 'first' yet.

$ git branch --set-upstream-to=upstream
fatal: No commit on branch 'first' yet.

$ git branch -c second
fatal: No commit on branch 'first' yet.

$ git branch [-c/-m] non-existent-branch second
fatal: No branch named 'non-existent-branch'.

With Git 2.39 (Q4 2022), "git branch --edit-description @{-1}"(man) is now a way to edit branch description of the branch you were on before switching to the current branch.

See commit 0dc4e5c (11 Oct 2022) by Rubén Justo (rjusto).
(Merged by Junio C Hamano -- gitster -- in commit c2058ea, 21 Oct 2022)

branch: support for shortcuts like @{-1}, completed

Signed-off-by: Rubén Justo

branch command with options "edit-description", "set-upstream-to" and "unset-upstream" expects a branch name.
Since ae5a6c3 (checkout: implement "@{-N}" shortcut name for N-th last branch, 2009-01-17, Git v1.6.2-rc0 -- merge), a branch can be specified using shortcuts like @{-1}.
Those shortcuts need to be resolved when considering the arguments.

We can modify the description of the previously checked out branch with:

 $ git branch --edit--description @{-1}

We can modify the upstream of the previously checked out branch with:

 $ git branch --set-upstream-to upstream @{-1}
 $ git branch --unset-upstream @{-1}


Use

git branch --list -v

to show an upstream branch:

git branch --list -vv

Add -r to show remotes only or -a to show remotes and local.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜