From: R. Steve McKown Date: Wed, 16 Mar 2016 23:22:54 +0000 (-0600) Subject: Add git-heads X-Git-Url: https://oss.titaniummirror.com/gitweb?p=git-utils.git;a=commitdiff_plain;h=31e5b27edfe737e8eed17523cc546f454d68498f Add git-heads Upstream source is https://github.com/seschwar/git-heads.git Importing commit b02ace9b18aabb53edfb8d8fda7dd8c48ba75afc --- diff --git a/git-heads b/git-heads new file mode 100755 index 0000000..5d8a78f --- /dev/null +++ b/git-heads @@ -0,0 +1,161 @@ +#!/bin/sh +## +## Copyright (c) 2010, Sebastian Schwarz +## +## Licensed under the MIT License; see accompanying `LICENSE` file. +## + +USAGE="[OPTION | git-log-OPTION]..." +LONG_USAGE="\ +Options: +-a, --all list all branches/heads +-b, --branch, --branches list branches + --contains [COMMIT] list only branches containing COMMIT + --head, --heads list heads; the default +-h, --help +-l, --local list only local branches/heads; the default + --merged [COMMIT] list only branches reachable from COMMIT + --no-merged [COMMIT] list only branches not reachable COMMIT +-r, --remote list only remote branches/heads + +For the git-log-OPTION see git-log(1)'s manual page." +OPTIONS_SPEC= +SUBDIRECTORY_OK="true" + +git_exec_path="`git --exec-path`" + +ifs="$IFS" +IFS=":" +for dir in $git_exec_path; do + test -f "$dir/git-sh-setup" -a -r "$dir/git-sh-setup" \ + && . "$dir/git-sh-setup" && break +done || { + echo "fatal: unable to find and source git-sh-setup in $git_exec_path" >&2 + exit 1 +} +IFS="$ifs" + +## A newline character. +N=" +" + + +branch_refs() { + git branch "$@" --color=never | sed -e 's/^[ *] //' \ + -e 's/^(no branch)$/HEAD/' -e 's/ -> .*$//' +} + + +## git-rev-list topologically sort the revs and annotates the with their +## children. Commits without children are heads. +childless_commits() { + branch_refs "$@" | git rev-list --children --stdin --topo-order \ + | sane_grep -v ' ' +} + + +## prefix PREFIX STRING +prefix() { + test "${2#$1}" != "$2" +} + + +main() { + if git config --get-colorbool color.log; then + color_auto="always" + else + color_auto="never" + fi + git_branch_args="--color=never" + git_branch_scope="" + git_log_args="--color=$color_auto$N--max-count=1" + mode="heads" + + while test "$#" -gt 0; do + case "$1" in + (-h|--help) ## Automatically handled by git(1) and git-sh-setup. Just + usage ## set $USAGE. + ;; + (-a|--all) + git_branch_scope="-a" + shift + ;; + (-l|--local) + git_branch_scope="" + shift + ;; + (-r|--remote) + git_branch_scope="-r" + shift + ;; + (-b|--branch|--branches) + mode="branches" + shift + ;; + (--head|--heads) + mode="heads" + shift + ;; + (--contains|--merged|--no-merged) + if test "$#" -lt 2 || prefix - "$2"; then ## $2 is + git_branch_args="$git_branch_args$N$1=HEAD" ## another + shift ## argument + else + git_branch_args="$git_branch_args$N$1=$2" + shift 2 + fi + mode="branches" + ;; + (--contains=*|--merged=*|--no-merged=*) + git_branch_args="$git_branch_args$N$1" + mode="branches" + shift + ;; + (--color) + case "$2" in + (always|never) + git_log_args="$git_log_args$N--color=$2" + shift 2 + ;; + (auto) + git_log_args="$git_log_args$N--color=$color_auto" + shift 2 + ;; + (*) + git_log_args="$git_log_args$N--color" + shift + ;; + esac + ;; + (--color=auto) + git_log_args="$git_log_args$N--color=$color_auto" + shift + ;; + (*) + git_log_args="$git_log_args$N$1" + shift + ;; + esac + done + + IFS="$N" + case "$mode" in + (branches) + branch_refs $git_branch_args $git_branch_scope + ;; + (heads) + childless_commits $git_branch_scope + ;; + (*) + die "unable to list commits for mode $mode" + ;; + esac | git rev-list --date-order --stdin --no-walk \ + | while IFS= read -r ref; do + echo + git log $git_log_args "$ref" -- || exit "$?" + done | tail -n +2 | git_pager +} + + +main "$@" + diff --git a/git-heads.1 b/git-heads.1 new file mode 100644 index 0000000..eb2980f --- /dev/null +++ b/git-heads.1 @@ -0,0 +1,111 @@ +.TH "GIT\-HEADS" "1" "" "GIT\-HEADS(1)" "" +.SH NAME +.PP +git\-heads \[en] show branches without any child commits with +\f[C]git\-log\f[](1) +.SH SYNOPSIS +.PP +\f[C]git\-heads\f[] [\f[C]\-\-all\f[] | \f[C]\-\-local\f[] | +\f[C]\-\-remote\f[]] [\f[C]\-\-branches\f[]] [(\f[C]\-\-contains\f[] | +\f[C]\-\-merged\f[] | \f[C]\-\-no\-merged\f[]) [\f[I]commit\f[]]] +[\f[I]git\-log\-option\f[]]\&... +.PP +\f[C]git\-heads\f[] [\f[C]\-\-all\f[] | \f[C]\-\-local\f[] | +\f[C]\-\-remote\f[]] [\f[C]\-\-heads\f[]] +[\f[I]git\-log\-option\f[]]\&... +.SH DESCRIPTION +.PP +Inspired by Mercurial's \f[C]heads\f[] command this Git command's +purpose is to display information about so\-called \[lq]heads\[rq]. +Heads are commits which have no child commits. +This also means that they are branches that have not been merged with +any other branch. +Do not confuse this definition of a head with Git's \f[C]HEAD\f[] ref +which points to the lastly checked out commit. +Furthermore you also must not confuse it with +\f[C]$GIT_DIR/refs/heads\f[], the directory where the references to your +local branches are stored. +.PP +\f[C]git\-heads\f[]' functionality is similar to the follow programs: +.IP +.nf +\f[C] +hg\ heads +git\ branch\ ...\ |\ xargs\ \-n1\ git\ log\ ... +git\ wtf +\f[] +.fi +.PP +It uses \f[C]git\-log\f[](1) to display the commit information. +.SH OPTIONS +.TP +.B \-a, \-\-all +Show both local and remote branches which have no child commits. +.RS +.RE +.TP +.B \-b, \-\-branch, \-\-branches +Show branches regardless whether they have child commits or not. +Similar to \f[C]git\-branch\f[](1). +.RS +.RE +.TP +.B \-\-contains [\f[I]commit\f[]], \-\-merged [\f[I]commit\f[]], +\-\-no\-merged [\f[I]commit\f[]] +Passed to \f[C]git\-branch\f[](1). +Implies \f[C]\-\-branches\f[]. +.RS +.RE +.TP +.B \-\-head, \-\-heads +Show only the tips of the branches without any children. +This is the default behavior. +.RS +.RE +.TP +.B \-l, \-\-local +Show only local branches. +This is the default behavior. +.RS +.RE +.TP +.B \-r, \-\-remote +Show only remote branches. +.RS +.RE +.TP +.B \f[I]git\-log\-option\f[] +These options are passed to \f[C]git\-log\f[](1) which is used to +display the matching branches. +.RS +.RE +.SH EXAMPLES +.PP +Show the last five commits for every remote branch which has been merged +with the current branch: +.IP +.nf +\f[C] +git\ heads\ \-\-remote\ \-\-branches\ \-\-merged\ \-\-format=oneline\ \-n\ 5 +\f[] +.fi +.PP +Show the last three commits on every head in a graph: +.IP +.nf +\f[C] +git\ heads\ \-\-all\ \-\-graph\ \-n\ 3 +\f[] +.fi +.SH SEE ALSO +.PP +\f[C]git\f[](1), \f[C]git\-branch\f[](1), \f[C]git\-log\f[](1), +\f[C]git\ wtf\ \-h\f[], \f[C]hg\ heads\ \-\-help\f[]. +.PP +Homepage: +.SH BUGS +.PP +If you find a bug please report it at +. +.SH AUTHORS +Sebastian Schwarz .