twolfson / sexy-bash-prompt

Bash prompt with colors, git statuses, and git branches.
MIT License
1.14k stars 155 forks source link

With a merge in progress, prompt renders as if the repo is clean #25

Closed rpdelaney closed 10 years ago

rpdelaney commented 10 years ago

I'm not yet sure how to handle incomplete merges better, but the default behavior (rendering as if clean) seems wrong. Maybe another unicode character would be better, or just an asterisk to suggest that the branch still contains uncommitted changes?

One of these symbols could be appropriate. Examples with unicode character short descriptions (in rough order of my preferences):

branch⑁ ocr chair branch⑃ ocr inverted fork branch⨝ set-theoretical join branch⧉ two joined squares branch⫓ subset above superset branch≟ questioned equal to branch≈ almost equal to

What do you think? Would you like a pull request?

twolfson commented 10 years ago

Can you elaborate on your incomplete merge further? I usually see the branch as dirty or unpushed in such cases.

rpdelaney commented 10 years ago

I was afraid you would ask that. Unfortunately I resolved the merge before I made this post :o) I'll see what I can do to recreate it.

twolfson commented 10 years ago

Ideally you can make a gist to reproduce it =)

rpdelaney commented 10 years ago

I got something half as good. I still had the window open in tmux and I was able to stitch this together from screenshots: http://imgur.com/96C30J6.png

The unexpected behavior came in after I did $ rm start-session.orig: I would expect the prompt to show that the branch was still dirty (since I had not concluded the merge) or at least unpushed (since the local branch was now ahead of origin).

twolfson commented 10 years ago

Ah, that makes sense. Technically, it is not ahead of origin since the final git commit has not been run.

For what it's worth, consider using git clean to remove .orig files.

I would anticipate git status to still indicate that we are in a merge but I guess not. We will need to explore alternative commands to see if we can determine this state.

I would say that this feels to coincide with a dirty state so we can probably add on to the parse_git_dirty command (as well as add tests).

This does raise my concerns about other incomplete states such as rebase, cherry-pick (this can have merge conflicts and requires --aborts), and bisect. However, let's leave those for another day.

twolfson commented 10 years ago

To encourage this thought, I think it is good to establish that the symbol reflects more/less git status (ahead, behind, files changed, merge in progress).

rpdelaney commented 10 years ago

Can you expand on your last comment? I'm not sure I follow your meaning.

twolfson commented 10 years ago

Sorry, it was more of a stream of consciousness note. It was a comment on what the philosophy behind the git portion of the prompt is (e.g. master*).

In specific, it was focusing on my observations and how I expect the symbol to present the current status to me (e.g. v for being behind, ^ being ahead, * for files changed/actions in progress).

twolfson commented 10 years ago

Alright, going to whip up a gist to reproduce this.

twolfson commented 10 years ago

All done, the gist can be found here:

https://gist.github.com/twolfson/8950891

twolfson commented 10 years ago

Taking a look at the rebase state now

todd at Euclid in ~/github/gist-sexy-bash-prompt-merge-status on (no branch)▲
$ git status
# rebase in progress; onto d374bd8
# You are currently rebasing branch 'dev/conflict' on 'd374bd8'.
#   (fix conflicts and then run "git rebase --continue")
#   (use "git rebase --skip" to skip this patch)
#   (use "git rebase --abort" to check out the original branch)
#
# Unmerged paths:
#   (use "git reset HEAD <file>..." to unstage)
#   (use "git add <file>..." to mark resolution)
#
#   both modified:      a.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
todd at Euclid in ~/github/gist-sexy-bash-prompt-merge-status on (no branch)▲
$ git checkout HEAD -- a.txt
todd at Euclid in ~/github/gist-sexy-bash-prompt-merge-status on (no branch)△
$ git status
# rebase in progress; onto d374bd8
# You are currently rebasing branch 'dev/conflict' on 'd374bd8'.
#   (all conflicts fixed: run "git rebase --continue")
#
nothing to commit, working directory clean
todd at Euclid in ~/github/gist-sexy-bash-prompt-merge-status on (no branch)△
$ git status --porcelain
todd at Euclid in ~/github/gist-sexy-bash-prompt-merge-status on (no branch)△
$ echo $?
0
twolfson commented 10 years ago

It looks like a rebase conflicted state generates .git/rebase-apply.

twolfson commented 10 years ago

I am starting to think we might want to introduce a new symbol as you initially suggested. Probably something that symbolizes broken since git is in a broken state.

twolfson commented 10 years ago

In a merge conflicted state, .git/MERGE_HEAD exists.

twolfson commented 10 years ago

In a cherry pick state, .git/CHERRY_PICK_HEAD exists.

twolfson commented 10 years ago

I am browing the git source code to find any edge cases I am missing. In the meantime, this looks promising:

https://github.com/git/git/blob/2b7ca916fcffafe9cfd967cce87436a9372ae969/t/t7512-status-help.sh

twolfson commented 10 years ago

There are a lot more in_progress functions than I expected. They seem to be what we want.

https://github.com/git/git/blob/v1.9-rc2/wt-status.c

twolfson commented 10 years ago

More symbol ideas:

# http://amp-what.com/#q=not%20equal
≠

# http://amp-what.com/#q=empty
∅

# http://amp-what.com/#q=gon
⤫
⤬

but... ideally we would have an icon that can be combined with the other states.

twolfson commented 10 years ago
# http://amp-what.com/#q=hour
⧖
⧗

# http://amp-what.com/#q=arrow
⌁

# http://amp-what.com/#q=triangle
◭
⧎

...or maybe we have to signify this is an important state (e.g. ! or color red). However, probably not.

twolfson commented 10 years ago

The hourglasses seem like the most likely choice since they re-use arrows and can be hollow/not. However, the symbol choice also depends on what the commands allow. I am going to go explore that further.

twolfson commented 10 years ago

I have a feeling we are going to be reproducing the top level if statements from this

https://github.com/git/git/blob/v1.9-rc2/wt-status.c#L1199-L1241

[[ -d .git/MERGE_HEAD ]] || etc...

However, this leads to more complication since it cannot easily be done with submodules or in a non top level directory (must resolve .git folder).

twolfson commented 10 years ago

Alright, so I coded up a working flavor for the merge only. I am going to try using it personally to verify that the merge flow feels normal. You can find the progress on git dev/symbolize.merge.in.progress.

https://github.com/twolfson/sexy-bash-prompt/compare/dev;symbolize.merge.in.progress

rpdelaney commented 10 years ago

Ok, I'll merge that branch into my fork and work some with it too.

twolfson commented 10 years ago

Maybe we should leave the symbol alone and add annotative text to the branch?

todd at Euclid in ~/github/gist-sexy-bash-prompt-merge-status on master (merge in progress)▲
twolfson commented 10 years ago

I have created another branch experimenting with using text as indicated in the previous comment.

dev/output.merge.in.progress

I will be experimenting with this one. I was uncomfortable with the same symbol for dirty and any in progress action and want to explore other options.

I am choosing to use text over a symbol (for now) because these are not regularly encountered symbols. The other symbols (dirty, unpushed, unpulled) are used on a regular basis and a small enough set to not be overbearing.

rpdelaney commented 10 years ago

I agree with your feelings that we should avoid ambiguity between dirty and an incomplete merge. It is useful to remind the user that the merge should be completed before doing anything else. Once there is a robust method for handling these states we can decide how to render it. :8ball:

twolfson commented 10 years ago

We already have the merge state properly being detected. I was trying to hold off on building the rest of them until we decided on a convention (small releases that way). My main concern with the the latest prompt is the length of merge in progress.

Additionally, I am concernaed about what happens when there is a rebase/cherry-pick/bisect in progress as well. Can we optimize it and is it even possible?

rpdelaney commented 10 years ago

Yes, I was just coming here to post this. This is what happens if I attempt to cherry-pick a commit from the same branch:

 # On branch AG-chicago 
 nothing to commit (working directory clean) 
 The previous cherry-pick is now empty, possibly due to conflict resolution.
 If you wish to commit it anyway, use:

    git commit --allow-empty

 Otherwise, please use 'git reset'

I have to git reset to continue work, but the prompt shows clean status.

rpdelaney commented 10 years ago

Here's another fun one:

$ git rebase -i
The previous cherry-pick is now empty, possibly due to conflict resolution.
If you wish to commit it anyway, use:

    git commit --allow-empty

Otherwise, please use 'git reset'
rebase in progress; onto ae62c13
You are currently rebasing branch 'master' on 'ae62c13'.

nothing to commit, working directory clean
Could not apply afeec62ad9278f0d8a86b9e6d9537cf0a08f0455... updated md5sums
ryan at mothership in ~/src/games/cfg-l4d2-server/test on (no branch)△

(no branch) is a big red flag that something is wrong, but maybe it could be more clear that the repo is dirty.

twolfson commented 10 years ago

Thanks for all the use cases. I haven't had a chance to try out the latest flavor yet (best suited for work) but should be making a head/tails on it soon.

Also, I am thinking about switching to square brackets for this case since those are not valid branch names and would distinguish themselves from (no branch).

twolfson commented 10 years ago

Played around with it some more, really digging the square bracket and command syntax. The user will already know it is in progress.

todd at Euclid in ~/github/gist-sexy-bash-prompt-merge-status on dev/conflict [merge]*
twolfson commented 10 years ago

Also, it is much shorter than the in progress text.

twolfson commented 10 years ago

Pushed latest flavor to dev/output.merge.in.progress branch.

twolfson commented 10 years ago

Finally got a merge conflict today, I didn't like the ordering of symbol and merge keyword. Also, it felt weird that the merge keyword and git info were the same color. I am trying out this flavor, so far it feels pretty good.

screen shot 2014-02-19 at 1 03 55 pm

twolfson commented 10 years ago

Today I learned we can use the following commands to get the .git directory path

git rev-parse --show-cdup # relative
git rev-parse --git-dir # absolute
twolfson commented 10 years ago

Sorry for the delay on this, I finally added/pushed that merge change to dev/output.merge.in.progress. I added a new prompt color prompt_git_progress_color.

twolfson commented 10 years ago

The latest set of changes can be found here: https://github.com/twolfson/sexy-bash-prompt/compare/dev;output.merge.in.progress

I have not updated the tests.

rpdelaney commented 10 years ago

No hurry. One more test case, though you might be catching this already:

git rebase -i
warning: Cannot merge binary files: addons/sourcemod/plugins/optional/l4d2_ai_damagefix.smx (HEAD vs. d6f6158... restored a couple missing plugins from promod353 package)

error: could not apply d6f6158... restored a couple missing plugins from promod353 package

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To check out the original branch and stop rebasing run "git rebase --abort".
Could not apply d6f6158... restored a couple missing plugins from promod353 package
l4d2 at chi05Y in ~/cfg-l4d2-server on (no branch)▲
twolfson commented 10 years ago

Marking this as resolved in 0.19.0 via #28. There will be a sequential PR to fill in the rebase, cherry-pick, etc gap