Fossil User Forum

Stuck on wrong branch
Login

Stuck on wrong branch

Stuck on wrong branch

(1) By Kirill M (Kirill) on 2024-11-23 20:45:23 [source]

Somehow both my Fossil checkouts ended up on the httpmsg-debug branch on the 735bd3dc check-in. Both have always been on trunk, with frequent runs of fossil update. I was puzzled that for a couple of weeks fossil update would report "Already up-to-date", until I noticed that I was on the wrong branch.

I'm curious how I could have ended up on that branch, though. The documentation for the update command say

The VERSION argument can be a specific version or tag or branch name. If the VERSION argument is omitted, then the leaf of the subtree that begins at the current version is used, if there is only a single leaf. VERSION can also be "current" to select the leaf of the current version or "latest" to select the most recent check-in.

I guess that I ended up on "the leaf of the subtree that begins at the current version", which was httpmsg-debug? This caught me off-guard.

(2) By Richard Hipp (drh) on 2024-11-23 21:00:12 in reply to 1 [link] [source]

See https://fossil-scm.org/home/ci_tags/28ea88e77039030f.

The first check-in of the httpmsg-debug branch was originally checked into trunk. But then I realized that I shouldn't be putting new features into a release candidate, so I move that check-in onto a branch. You probably did a "fossil update" while that check-in was still on trunk, then when I moved it off onto a branch, you got carried along with it. That happens sometimes.

You can always do "fossil up trunk" to make sure you have the latest trunk check-in.

I have been advocating for a web-based check-in process that does things like:

  • Allow you to preview the formatting of your check-in comment.

  • See a timeline-style graph of where in the tree the check-in is going.

  • See better web-based diffs.

If that capability had been available, you would have seen immediately that you were checking into a branch off of a branch and not a branch off of trunk, and could have aborted the check-in and done "fossil up trunk", retested, then done your "fossil commit --branch bv-infotool --ui" again. But, alas, we do not yet have a "--ui" option for "fossil commit".

(3) By Andy Bradford (andybradford) on 2024-11-23 21:19:43 in reply to 1 [link] [source]

> fossil update would report "Already up-to-date", until I noticed that
> I was on the wrong branch.

Yeah,  it's  possible  that  the   output  from  "fossil  update"  isn't
sufficient to  provide you  with proper  situational awareness.  It does
include the branch that you're on in "tags:"

tags:         trunk
changes:      None. Already up-to-date

But maybe people don't bother looking at all the output and only look at
the "changes:" line. In which case, maybe we should instead have changes
also include  a statement about  which branch  the changes were  on. For
example:

changes:      No changes on <branch>.  Already up-to-date

Then when  the branch changes,  and you think  you're on trunk  (or some
other branch), you  would recognize it immediately, instead  of a couple
of weeks later?


Andy

(4) By jvdh (veedeehjay) on 2024-11-23 22:04:44 in reply to 3 [link] [source]

this (unexpectedly not on trunk after some update) has only hit me once but it can indeed happen so more prominent notification of the user would be good in the CLI. since "tags" is maybe too generic (since it includes not only branch names) and comes before the "up to date" message, I think a final separate line after the "changes" line like

Current branch: trunk

(or "you are on branch xxx") might be preferable.

(5) By Andy Bradford (andybradford) on 2024-11-24 04:19:12 in reply to 4 [link] [source]

I opted to go with updating the  "changes:" line. I played with having a
separate line of output, but I think  I prefer the same line over having
yet another line of  output to deal with. I've committed  it to a branch
for now for  comments just in case  some object to changing  a line that
already exists.  I know that  we don't  make promises in  Fossil command
output but wanted to also discuss it.

https://www.fossil-scm.org/home/info/bb9150c403e78db3

Demonstration:

$ fossil status
repository:   /tmp/once.fossil
local-root:   /tmp/once/
config-db:    /home/amb/.fossil
checkout:     8555051cdd35046ba9c8d13bc39e2a07ad83b755 2024-11-24 03:57:15 UTC
parent:       ba98361edb8bc0c45ec479bec77ef9dc19cec671 2024-11-24 03:01:00 UTC
tags:         trunk
comment:      wait (user: amb)


In another clone  and working checkout I decide that  this commit should
be in a different branch:

$ fossil amend 8555051cdd35 --branch newfeature
hash:         8555051cdd35046ba9c8d13bc39e2a07ad83b755 2024-11-24 03:57:15 UTC
tags:         newfeature
comment:      wait (user: amb)


Now, when I update, it will show  me that there are no changes, but also
that the branch was renamed:

$ fossil update
Pull from file:///tmp/new.fossil
Round-trips: 2   Artifacts sent: 0  received: 1
Pull done, wire bytes sent: 701  received: 3086  remote: 
-------------------------------------------------------------------------------
checkout:     8555051cdd35046ba9c8d13bc39e2a07ad83b755 2024-11-24 03:57:15 UTC
tags:         newfeature
comment:      wait (user: amb)
changes:      None. Already up-to-date.  Branch changed from trunk to newfeature.

However, now  that I look at  the output, I'm  not sure I like  the fact
that it has to  wrap on a standard terminal size.  Clearly the length of
this also depends on the length  of branch names. This might indeed lend
itself more towards being on a separate line.


And again, if no changes, there is no additional output:

$ fossil update
Pull from file:///tmp/new.fossil
Round-trips: 1   Artifacts sent: 0  received: 0
Pull done, wire bytes sent: 331  received: 1490  remote: 
-------------------------------------------------------------------------------
checkout:     8555051cdd35046ba9c8d13bc39e2a07ad83b755 2024-11-24 03:57:15 UTC
tags:         newfeature
comment:      wait (user: amb)
changes:      None. Already up-to-date.

I didn't think  it would be good to always  output the "branch:" because
that information will almost always  likely be redundant given what's in
"tags:".

Perhaps conditionally output something like:

changes:      None. Already up-to-date.
achtung:      Branch changed from trunk to newfeature.

Something else?

Andy

(7) By Kirill M (Kirill) on 2024-11-24 20:03:35 in reply to 5 [link] [source]

I don't think any change in the output is necessary, really. The information is already there in the tags, it's up to the user to keep attention. But maybe adding some words in documentation/FAQ could perhaps be appropriate?

(8) By Andy Bradford (andybradford) on 2024-11-26 19:32:33 in reply to 7 [link] [source]

> I  don't think  any change  in the  output is  necessary, really.  The
> information is already there in the tags

Normally I  would agree that no  additional output is necessary,  but in
this  case it  comes up  often  enough that  I  think at  least a  small
change  is warranted.  Also, I  think  it even  surprises veteran  users
occasionally, so  this might help  minimize confusion. If they  miss the
additional output,  then I don't know  to say. My only  question at this
point is whether the information can be presented better?

I think  this is now  ready to  go in if  someone wants to  "review" it.
Basically it  will append "Branch changed  from X to Y."  if your update
switched branches and you did *not* provide a VERSION argument:

https://www.fossil-scm.org/home/timeline?r=show-branch-change

Andy

(10) By Stephan Beal (stephan) on 2024-11-26 19:37:28 in reply to 8 [link] [source]

Also, I think it even surprises veteran users occasionally,

🙋‍♂️

The first time it happened to me i assumed it was a horrible fossil bug. Once you've seen it, and understood why it happens, it's a no-brainer to avoid, but it's indeed surprising the first time one stumbles over it.

FWIW, i really like your src:2ef47b81 tweak. That's a nice idea.

(11) By Andy Bradford (andybradford) on 2024-11-26 19:55:53 in reply to 10 [link] [source]

> FWIW, i really like your src:2ef47b81 tweak. That's a nice idea.

Yeah, as I thought about it, I  didn't really want to see it everytime I
switched  branches and  I figured  that  most people  know what  they're
getting if they provide a 3rd argument.

Also, thanks for the demonstration---I  wondered how to do that src:HASH
trick. I knew it  could be done, but didn't want  to bother scouring the
source to figure it out.

I'll merge this later today (or tomorrow) if there are no objections.

Thanks,

Andy

(12) By Richard Hipp (drh) on 2024-11-26 20:12:41 in reply to 11 [link] [source]

The change you are wanting to commit appears to be just a warning that "fossil update" might leave you on the same check-in, but on a different branch, due to tags added by a third-party? Do I have that right?

That seems to be a reasonable step. But what if the branch name change happens just before the check-in occurs? What if the tag that moves the branch of the parent check-in arrives during the automatic "pull" that occurs at the beginning of the commit? Seems like it would still be easy for a person to get a check-in to the wrong branch without realizing it.

I was thinking that there might also be a check on the "commit" command such that if:

  1. The parent check-in has been the subject of a branch-change tag, and

  2. The user who issued the branch-change tag is different from the user doing the current check-in,

Then issue a warning message with a confirmation prompt, similar to the way we do now if there is an issue with line endings or a fork or a timestamp issue or other problem. Perhaps something like:

The parent check-in [abcd1234] was originally on branch 'trunk' but is now on branch 'new-feature'. Continue with the check-in? (Y/n)

(13.2) By Andy Bradford (andybradford) on 2024-11-26 21:21:59 edited from 13.1 in reply to 12 [link] [source]

> The change you are wanting to commit appears to be just a warning that
> "fossil  update" might  leave  you  on the  same  check-in,  but on  a
> different branch, due  to tags added by a third-party?  Do I have that
> right?

Yes, update  will update you to  the tip of whatever  current branch tag
you happen to be on, and if it changes you get additional output telling
you that this has happened. The intent was merely to keep the person who 
is running "fossil update" abreast of  a change that might impact future
work so there is less of a surprise later on.             

However, you also bring up some  other good points about what happens if
the tag changes  as part of an autosync while  committing. They will not
be  given the  opportunity  of correcting  or even  notice  that is  has
changed.

Before I merge this branch I'll look into your proposed idea that if the
tag  changes while  committing  that  it prompts  to  continue with  the
checkin. Right  now what it does  is automatically pull and  it does not
display any kind of warning (and  because the update command was not run
there is  no actual output  to show that  the branch changed).  The only
thing that might clue  me in is that while editing  my commit comment, I
might notice that suddenly the tags are different:

# Enter a commit message for this check-in. Lines beginning with # are ignored.
#
# user: amb
# tags: newbranch
#
# EDITED     file

I'll start looking at enhancing this.

Thanks for the idea.

Andy

(14) By Andy Bradford (andybradford) on 2024-11-27 19:56:00 in reply to 12 [link] [source]

> Then issue  a warning message  with a confirmation prompt,  similar to
> the way we do now if there is  an issue with line endings or a fork or
> a timestamp issue or other problem.

This is now implemented on the same branch:

https://www.fossil-scm.org/home/timeline?r=show-branch-change

Example:

$ fossil ci --no-prompt -m test
Pull from file:///tmp/master.fossil
Round-trips: 2   Artifacts sent: 0  received: 1
Pull done, wire bytes sent: 737  received: 3845  remote: 
parent check-in [c196dcaced] changed branch from 'trunk' to 'j'
Abandoning commit because branch has changed

It also works for interactive commits:

$ export EDITOR=ed
$ fossil ci
Pull from file:///tmp/master.fossil
Round-trips: 1   Artifacts sent: 0  received: 0
Pull done, wire bytes sent: 363  received: 1952  remote: 
ed ./ci-comment-CB666124B628.txt
131
1,$p
Prova.
# Enter a commit message for this check-in. Lines beginning with # are ignored.
#
# user: amb
# tags: l
#
# EDITED     file
1
Prova.
s/Prova/Prova Secondo/
w
139
q
Pull from file:///tmp/master.fossil
Round-trips: 2   Artifacts sent: 0  received: 1
Pull done, wire bytes sent: 739  received: 4079  remote: 
parent check-in [c196dcaced] changed branch from 'l' to 'm'
continue (y/N)? n
Abandoning commit because branch has changed


How does it look?

Andy

(15) By Florian Balmer (florian.balmer) on 2024-11-28 05:40:08 in reply to 14 [link] [source]

Does and/or should the --force option disable the prompt?

(I'm not sure, but I feel there should be a way to get stuff done by scripting, even if subsequent manual improvements may be necessary.)

(17) By Richard Hipp (drh) on 2024-11-28 12:08:54 in reply to 15 [link] [source]

I agree that --force should prevent the warning and continue prompt and just let the commit go through.

(19) By Andy Bradford (andybradford) on 2024-11-29 16:25:07 in reply to 15 [link] [source]

> Does and/or should the --force option disable the prompt?

It does now.  Thanks for the suggestion.

Andy

(16) By Richard Hipp (drh) on 2024-11-28 12:07:35 in reply to 14 [link] [source]

Thank you for the patch. However, I don't think it does quite what I had in mind.

A quick reading of your code suggests that it only issues the warning if the branch change was received during the autosync that happens at the start of the commit. I want it to detect a branch change that happens at any time prior to the commit. I suggest detecting that by searching for CONTROL artifacts that modify the branch of the primary parent check-in. You can do that using a query against the TAGXREF table. The conditions are:

  • There exists a TAGXREF entry that changes the branch of teh parent check-in.

  • That TAGXREF entry was originated from a user other than the user doing the current check-in.

The tricky bits will be detecting cases where the branch was changed multiple times, and figuring out the original branch of the parent check-in for use in the warning message. But it should all be doable with SQL - no need to parse artifacts, I don't think.

So, the branch change might have happened and have been synced days before the commit, and the committer might be fully aware of it. That's why this is a warning and not a fatal error. The user can always select "commit anyhow" in the case of a false positive.

(18) By Andy Bradford (andybradford) on 2024-11-29 16:14:11 in reply to 16 [link] [source]

> I want it to detect a branch change that happens at any time prior to
> the commit.

Alright, let me see if I can figure that out. Also for clarification, do
you also mean that  if I run "fossil status" after  a previous "pull" or
"sync" operation has brought in a branch name change that applies to the
working checkout,  that it will  also issue a  warning then? Or  is this
a "commit" warning only?


> So, the  branch change might have  happened and have been  synced days
> before the commit, and the committer might be fully aware of it.

If  the branch  change was  synced  days ago,  then the  "state" of  the
repository has already changed. To detect the change "now" at the moment
of "commit",  are you suggesting  looking at  the tagxref table  for the
latest branch tag that is "newer"  than the current working checkout and
issuing a warning then?

Thanks,

Andy

(20.2) By Andy Bradford (andybradford) on 2024-11-29 16:59:14 edited from 20.1 in reply to 18 [link] [source]

> looking at the tagxref table for the latest branch tag that is "newer"
> than the current working checkout and issuing a warning then?

Or does the  tagxref table get updated during a  sync/pull, and the very
presence  of an  entry in  that table  for the  current checkout  rid is
evidence that the branch has changed? [seems that's not quite the case]
[but I might be able to use srcid and origid]

In which case, all that is needed to be done is find out the branch name
*before* that change happened. You did mention sorting out if there were
multiple changes and finding the name *before* all of those changes.

Let me know if I'm on the wrong track.

Thanks,

Andy

(21) By Richard Hipp (drh) on 2024-11-29 23:58:00 in reply to 20.2 [link] [source]

You seem to be on the right trail. All of the auxiliary tables, including tagxref, are updated automatically whenever new artifacts are received, either by sync/pull or whatever other means. So it is sufficient to query the tagxref table, I believe.

To figure out the original name of the branch, look for the cancel tag on the symbol. For example, see the tags associated with the check-in that started this whole discussion:

https://fossil-scm.org/home/ci_tags/28ea88e77039030f

In this case, there is only a single tag, specifically artifact d75d757ce. That one artifact simultaneously does:

  1. Change the branch to httpmsg-debug
  2. Adds the symbolic name httpmsg-debug
  3. Changes the comment
  4. Drops the symbolic name httpmsg-debug

This results in four TAGXREF entries, which you can see using the following SQL:

SELECT tagxref.*, tag.tagname
  FROM blob, tagxref, tag
 WHERE blob.uuid GLOB '28ea88e77039*'
   AND tagxref.rid=blob.rid
   AND tag.tagid=tagxref.tagid;

Tag artifacts are processed in timestamp order. So if there are multiple branch changes on a single check-in, you can get the current branch name from the most recent change, and the original branch name from the cancel sym-* tag of the first change. On the other hand, I find zero instances of a check-in branch being changed more than once in either Fossil or SQLite, so I conclude that is an uncommon occurrence and so you shouldn't worry too much about it. If the warning message gets the wrong original branch name when the branch has been renamed multiple times, I think that will be ok, as long as it gets one of the prior branch names.

(22) By Andy Bradford (andybradford) on 2024-12-01 02:04:12 in reply to 21 [link] [source]

> To figure out the original name of the branch, look for the cancel tag
> on the symbol.

So it seems I  went a different direction in using  the tagxref table. I
wonder if it  would have been easier  to look for the cancel  tag as you
suggest.

This is what I've been testing:

https://www.fossil-scm.org/home/info/0aabb6bcacd627eb

Is this unncessarily complicated at this point? I'm not sure. Let me see
what it would take to instead use the cancel tag.

Thanks for the pointers.

Andy

(6) By brickviking on 2024-11-24 05:20:03 in reply to 3 [link] [source]

If you're using bash, there's a bash prompt function you could tailor for your needs. That's not much good outside of bash though. At least in my case, it slows down the initial prompt display on entering a checkout with a large number of changes. Sqlite3 and fossil-scm are both good examples of this, where on my machine, it can take a second to see the initial prompt. It seems to work perfectly well after that.

Here's an example of a bash prompt with changes against the checkin:

viking@host: (trunk) ~/src/c/fossil-scm/fossil $

The clean checkin would have cyan brackets instead, like this:

viking@host: (trunk) ~/src/c/fossil-scm/fossil $

There is other stuff you could do, of course - but that's about as complicated as I want to get.

RTDoc Brickviking
(Post 57)

(9) By Andy Bradford (andybradford) on 2024-11-26 19:33:45 in reply to 6 [link] [source]

> Here's an example of a bash prompt with changes against the checkin:

I'm not a  bash user, but I'll  admit that's a fun and  clever trick for
bash for those who are.

Andy