bill-auger / git-branch-status

A shell script that prints out pretty git branch sync status reports
GNU General Public License v3.0
237 stars 34 forks source link

Script-friendly output? #11

Closed jml closed 4 years ago

jml commented 5 years ago

Hello,

Thanks for this neat tool. I was hoping to use it to help delete local branches that I've deleted from the remote.

To do this, I'd want something like git-branch-status -l but only emitting the local branch name in plain text, with no colours.

I tried doing this:

$ git-branch-status -l | grep '(no upstream)' | awk '{{ print $2; }}' | xargs git branch -d
error: branch '?[0;37mbranch-name?[0m' not found.

But as you can see, the ANSI color codes are included in the output.

Would it be possible to have non-colour output, and to select which columns are shown?

Thanks, jml

bill-auger commented 5 years ago

everything is possible with free software - its more a question of how generally useful or novel would such a feature be - someone suggested before a "porcelain" machine-friendly output (issue #3); but the standard git commands alone are sufficient for most scripting tasks - the core functionality of this script is very simple as shown in that previous issue - the defining feature of this script, and the primary use-case, is for the pretty formatted human-friendly output

for example:

something like git-branch-status -l but only emitting the local branch name in plain text

that above is describing the standard output of the git branch command

the simplest way to remove the color codes and select arbitrary fields would be to set all the color codes (CWHITE, CRED, CGREEN, CYELLOW, CBLUE, CEND) to empty strings, then use awk, just as you have, or cut -d '|' -f N to select the fields

i suppose i could add a new switch to disable color per run - i will leave this open as a feature request to see if any others up-vote it

jml commented 5 years ago

something like git-branch-status -l but only emitting the local branch name in plain text

that above is describing the standard output of the git branch command

I should have been more clear. I don't want git branch output, I want git branch output, but filtered for the branches that have no upstream.

bill-auger commented 5 years ago

for now, i would just copy the script to a new name and set the color codes to empty strings in one of them

bill-auger commented 4 years ago

i added a feature to enable/disable the colors - it is configurable with either a config file or with environment variables - the file:: 'gbs-config.sh.inc.example' explains it

the master branch is up-to-date with the development branch now

liverwust commented 4 years ago

Not to reopen a closed thread, but I started work on something like this: https://github.com/liverwust/git-branch-status/tree/plain-columns

You can scroll down to see a screenshot of the intended output. My intention is to complement -- not replace -- the USE_ANSI_COLOR option with a USE_PLAIN_COLUMNS option. It would be possible to use both (like in the screenshot), or to use colorful plain columns, or to use standard tables (not plain columns) with colors disabled, etc. Note that the screenshot is simulated — no code has actually been written yet :-)

@bill-auger If I continued this and submitted a PR, would it be of interest? Or does this diverge from the purpose of the script?

bill-auger commented 4 years ago

i may consider that, if it were minimally non-intrusive; but really, no new code is needed in order to accomplish the stated purpose, or to produce the proposed simulated output - there is currently a fundamental obstacle which prevents implementing anything like this though

the 'USE_ANSI_COLOR ' env var was added specifically with machine-parsing in mind, specifically to satisfy this feature request - the reason why i closed this this ticket, is because i believe that the 'USE_ANSI_COLOR ' var alone, is fully sufficient - the rationale is that: the fancy output is already regular - the color codes were the only complication

to elaborate: the comparison relationships can be inferred by the section header lines which all (and only those lines) include the pattern: ' <-> '; and the pattern: ' | ', can be only found in the data lines between sections - that is intentionally so - rather than the pipe char being seen as an obstacle to parsing; it is the very thing which makes parsing as simple and robust as possible, without the need of a new CLI switch and dedicated processing for plain reports

the simulated output as proposed, could be generated like so:

GBS_USE_ANSI_COLOR=0 git-branch-status -a | grep  '|' | tr -d '|'

or with the section headers:

GBS_USE_ANSI_COLOR=0 git-branch-status -a | grep -E '<->|\|' | tr -d '|'

or as a shell function:

git-branch-status-plain() { GBS_USE_ANSI_COLOR=0 git-branch-status $* | grep  '|' | tr -d '|' ; }

or for fixed-width columns:

git-branch-status-plain()
{
  OUTPUT_FMT='$20s %$20s %$20s %$20s\n'
  GBS_REGEX='.*| ([^ ]*) *| \((.*)\) *| \((.*)\) *| [^ ](.*) *|.*'

  printf "${OUTPUT_FMT}" 'BASE-BRANCH' 'N-AHEAD' 'N-BEHIND' 'COMPARE-BRANCH'
  while read line
  do [[ "$line" =~ ${GBS_REGEX} ]] && printf "${OUTPUT_FMT}" ${BASH_REMATCH[0]} ${BASH_REMATCH[1]} ${BASH_REMATCH[2]} ${BASH_REMATCH[3]}
  done < <(GBS_USE_ANSI_COLOR=0 git-branch-status $* | grep  '|' | tr -d '|' )
}

IMHO that is simple enough - i assume that anyone who wants to use this script, has sufficient shell-foo to write such helpers on their own - OTOH, i suppose the git-branch-status-plain() function above, could be a new file in the repo named: git-branch-status-plain', if that satisfies your use-case - not to discourage your ambition o/c; but perhaps i do not understand your use-case, which would make this not as trivial to accomplish as i am assuming

an external file would be preferable currently, because the fundamental problem with implementing this (or any new features, really), is that parsing of CLI args is very crude - the program can accept exactly zero or one CLI options - the option given (including none) implicitly determines which report mode to run, and each is strongly coupled to the args which follow them, and in a precise order - in other words, if a new CLI option were added for a plain report, it could only ever produce one type of report, such as the '--all' report - it is the same reason why '--dates' can not be used for local or remote reports; and why '--verbose' always runs the '--all' report with dates enabled

the functionality of the 'USE_ANSI_COLOR ' env var would be better as a CLI option; but i am hesitant to add any new options before re-working CLI args parsing to use getopts, for example - that is the reason why i implemented that functionality as an env var - perhaps you would like to take on that task - it is currently a barrier to adding any complex features

bill-auger commented 4 years ago

just some notes about the proposed columns:

im not sure what is the intention of the 'REMOTE' column; but it would be redundant, strictly speaking; because that information is already easily parsed - all entries which display a remote branch, have the remote name present in the right-most branch name column - that is currently complicated by the fact that remote and branch names may contain the slash char '/'; but the remote and branch names could be separated in the reports, by a space char instead - all entries which do not display a remote branch, have '(no remote)' in the right-most branch name column

the semantics of "LBRANCH" and "RBRANCH" are accurate; but "LSYNC" and "RSYNC" are somewhat misleading - to be clear, "L" and "R" indicate "left" and "right", but not "local" or "remote" - local branches are sometimes shown in the right-most-column; and remote branches are sometimes shown in the left-most-column - the comparison is always with respect to the left branch (if present), and against the right branch (if present) - that is the reason why the remote reports present remotes in the right-most column - otherwise, the semantics of ahead/behind would need to be inverted for remote reports, which i assumed would be a source of confusion

the column labeled: "LSYNC", indicates the number of commits for which the left branch is behind the right branch, with the semantics: "this number of commits exist on the right branch, which are not related to the left branch" - likewise, the column labeled: "RSYNC", indicates the number of commits for which the left branch is ahead of the right branch, with the semantics: "this number of commits exist on the left branch; which are not related to the right branch"

so, more accurate labels for those would be either "L-BEHIND" or "R-AHEAD" instead of "LSYNC"; and either "L-AHEAD" or "R-BEHIND" instead of "RSYNC"