Search code examples
gitvisual-studio-codeworkflowgit-merge

What is the most used healthy programmer's workflow for stale branches' merging into branch main?


I have many stale branches and I wish to keep some as archived and for others to merge them into the main branch. But they have formed so many threads in the git log --graph --oneline --all view that I need a more visual tool for this, or a better suited algorithm. I would use SourceTree for its colorful branches' display but it is not available on Linux.

I have visual tools but I feel that without an user manual I can't get the best results from them (e.g. GitLens extension for VS Code). Like I have the freedom but I don't have patterns of usage formed in my brain. I could try a few months or years with this chaos in my mind but I prefer to ask.

I must say that through the term "healthy" I might, in some contexts, also understand "efficient".

I describe in pseudo-code what I want:

for each not-merged-into-A branch X (A is another branch)
  start a group
  show branch X's name
  for each not-merged-into-A commit Y in X, fixed order (ascending or descending)
    start a subgroup
    show commit ID Y
    for each changed file Z in Y, grouped by parent path, fixed order (lexicographically)
      in column 1 show relative file path for Z
      in column 2 show the change that occurred to Z, eventually colorfully and hopefully with changes counters
    end the subgroup
  end the group

Through the term "group" I mean a visually separated region of output.

I don't mind if it can be done in VS Code with some available extension or without.

Thank you.


Solution

  • git log has many (many many) options, among which :

    • --simplify-by-decoration : allows to have a more compact view of your history
    • --decorate-refs : when combined with the above, allows you to select some references to keep (e.g : only branches, only tags, only branches starting with feature/ ...)
    • --name-only or --name-status : display the list of files modified between two commits displayed in the resulting graph

    You can list branches (or references) not merged into master yet using :

    • git branch --no-merged master
    • git for-each-ref --no-merged master

    Dealing with many branches in only one display would probably still be too much, but the above options may probably help you to get what you want using isolate calls to git log master that/branch.

    Also note : --name-only and --name-status are valid options for git diff

    # the following will show the list of files modified by my/branch
    # since it forked from master (<- 3 dots between the two names)
    git diff --name-status master...my/branch
    

    An example : using the repository for git (mirrored at github.com/git/git)

    1. With --simplify-by-decoration, git log will output a simplified graph where the only commits kept in the display are :
    • commits pointed at by a ref (e.g : a branch, a tag, or a remote branch)
    • fork and merge points of such references
    $ git log --graph --oneline --all --simplify-by-decoration
    * 33bc620fd1 (origin/seen) Merge branch 'ab/config-based-hooks-base' into seen
    * 670b81a890 (HEAD -> master, origin/next, origin/master, origin/HEAD) The second batch
    * ebf3c04b26 (tag: v2.32.0, origin/maint) Git 2.32
    * c09b6306c6 (tag: v2.32.0-rc3) Git 2.32-rc3
    * 4e42405f00 (tag: v2.32.0-rc2) Git 2.32-rc2
    * de88ac70f3 (tag: v2.32.0-rc1) Git 2.32-rc1
    * bf949ade81 (tag: v2.32.0-rc0) Git 2.32-rc0
    * 48bf2fa8ba (tag: v2.31.1) Git 2.31.1
    * a5828ae6b5 (tag: v2.31.0) Git 2.31
    * 13d7ab6b5d (tag: v2.31.0-rc2) Git 2.31-rc2
    *   56a57652ef Sync with Git 2.30.2 for CVE-2021-21300
    |\  
    | * 94f6e3e283 (tag: v2.30.2) Git 2.30.2
    | *   e4e68081bb Sync with 2.29.3
    
    1. Using --decorate-refs=<pattern>, you can restrict the list of references you want to see :
    # only see remote branches :
    $ git log --oneline --graph --all --simplify-by-decoration \
        --decorate-refs=refs/remotes/origin
    * 33bc620fd1 (origin/seen) Merge branch 'ab/config-based-hooks-base' into seen
    * 670b81a890 (origin/next, origin/master, origin/HEAD) The second batch
    * ebf3c04b26 (origin/maint) Git 2.32
    | * 2cbe4a3e12 (origin/todo) What's cooking (2021/06 #06)
    | *   ee21229929 Merge in "What's cooking" history
    | |\  
    | | * 7d77f2e9cc What's cooking (2008/06 #01)
    | * 1bd90415de Keep track of to-do document.
    
    
    # only see local branches (note : I only checked out 'master' and 'todo' locally)
    # and tags starting with 'v2.32.' :
    $ git log --oneline --graph --all --simplify-by-decoration \
        --decorate-refs=refs/heads --decorate-refs=refs/tags/v2.32.*
    * 670b81a890 (master) The second batch
    * ebf3c04b26 (tag: v2.32.0) Git 2.32
    * c09b6306c6 (tag: v2.32.0-rc3) Git 2.32-rc3
    * 4e42405f00 (tag: v2.32.0-rc2) Git 2.32-rc2
    * de88ac70f3 (tag: v2.32.0-rc1) Git 2.32-rc1
    * bf949ade81 (tag: v2.32.0-rc0) Git 2.32-rc0
    | * 2cbe4a3e12 (todo) What's cooking (2021/06 #06)
    | *   ee21229929 Merge in "What's cooking" history
    | |\  
    | | * 7d77f2e9cc What's cooking (2008/06 #01)
    | * 1bd90415de Keep track of to-do document.
    
    1. If you add --name-status, you will see a list of modified files :
    $ git log --graph --oneline --name-status --all --simplify-by-decoration
    * 670b81a890 (master) The second batch
    | M     Documentation/Makefile
    | A     Documentation/RelNotes/2.33.0.txt
    | M     Documentation/config/color.txt
    | M     Documentation/diff-options.txt
    ...
    | M     t/test-lib.sh
    | M     trace2/tr2_dst.c
    | M     transport.c
    * ebf3c04b26 (tag: v2.32.0, origin/maint) Git 2.32
    | M     GIT-VERSION-GEN
    | R072  po/README       po/README.md
    | M     po/TEAMS
    ...
    | M     po/zh_TW.po
    | M     t/lib-parallel-checkout.sh
    | M     write-or-die.c
    * c09b6306c6 (tag: v2.32.0-rc3) Git 2.32-rc3
    | M     GIT-VERSION-GEN
    | M     builtin/fsck.c
    | M     contrib/completion/git-completion.bash
    | M     contrib/completion/git-completion.zsh
    * 4e42405f00 (tag: v2.32.0-rc2) Git 2.32-rc2
    | M     GIT-VERSION-GEN
    ...
    

    That list is the list of files modified between the two commits displayed in that graph.

    For example : the only file modified by commit 670b81 (the current state of master) is :

    $ git show --name-status master
    commit 670b81a890388c60b7032a4f5b879f2ece8c4558 (origin/next, origin/master, origin/HEAD, master)
    Author: Junio C Hamano <gitster@pobox.com>
    Date:   Mon Jun 14 13:23:28 2021 +0900
    
        The second batch
        
        Signed-off-by: Junio C Hamano <gitster@pobox.com>
    
    M       Documentation/RelNotes/2.33.0.txt
    

    The list :

    | M     Documentation/Makefile
    | A     Documentation/RelNotes/2.33.0.txt
    | M     Documentation/config/color.txt
    ...
    

    is the complete list of files modified between master and tag: v2.32.0 (you would get the same list with : git diff --name-status v2.32.0 master).