Fossil Forum

RFC: fossil stash --interactive
Login

RFC: fossil stash --interactive

RFC: fossil stash --interactive

(1) By mark on 2022-04-28 13:23:03 [link] [source]

I recently implemented this in fnc. It serves a similar purpose to
git add -p except I think it's more inline with the Fossil ethos
of testing full commits before performing a check-in as you select which
hunks in the current checkout you want to stash. They're then stashed,
leaving your checkout with only those changes kept, which can be tested
and committed. Stashed changes can be retrieved, rinse, and repeat.
Whereas git add -p leaves your checkout with all (staged and unstaged)
changes, so any testing does not represent the changes being committed.

In any case, I'm posting for comments because I think this can be
implemented in Fossil, except each hunk will be printed to stdout, like
Git, rather than a curses interface. Before starting work on it, is
there any interest or is this not wanted in Fossil?

Why? In my case, I have a habit of working on b when x is brought to
my attention. If x is trivial, I find it simpler to do x in the same
work tree rather than drop to my shell, mkdir ../tree-x && cd ../tree-x
then fossil open repo and so on. Often, y and z join the party, and
I have a checkout that I'd rather introduce as a few individual commits
rather than one with the log message, "While here, ...". In these events,
this stash option comes in handy. Sure, there are existing ways in such
a case to produce individual commits, but none as streamlined, and all
require more context switching.

(2) By Warren Young (wyoung) on 2022-04-28 14:47:41 in reply to 1 [link] [source]

This sounds useful, though I don't know how long it will be before I have a battlefield grade test case to try it on, since I've trained myself out of writing overlapping change sets.

On reading your docs (which don't yet mention --interactive by the way) it seems to me that your current design is confusing. The default mode of interaction (without a subcommand) is to get/pop interactively, but apparently under this new flag, you have to give a flag to get interactive behavior back. It seems to me that, given your tool's 0.10 version number, you have the freedom to rationalize this and make all modes interactive, and skip the flag. If one wants unconditional push/pop, use regular Fossil.

Also, "get" in fnc vs "apply" in Fossil is confusing. You should use the same verbs Fossil does to reduce friction.

As for putting this into Fossil proper, if my recollection of a general objection to adding ncurses things to Fossil is correct, then I say leave this feature in fnc. I don't see why you'd do this sort of thing any other way.

I'll be happy to add a mention for this to the gitusers doc when you've got the feature stable at the function and UI levels.

(5.1) By mark on 2022-04-29 06:25:10 edited from 5.0 in reply to 2 [source]

This sounds useful, though I don't know how long it will be before I have a battlefield grade test case to try it on, since I've trained myself out of writing overlapping change sets.

That's okay. This is a feeler for whether this is wanted in Fossil. I'm
looking for opportunities to give back and share useful contributions with
the project that also scratch a personal itch. If the project doesn't find
it useful, I already have the means to use it myself. But any testing you
have the time and desire to throw at it would be great. Thanks!

On reading your docs (which don't yet mention --interactive by the way) it seems to me that your current design is confusing. The default mode of interaction (without a subcommand) is to get/pop interactively, but apparently under this new flag, you have to give a flag to get interactive behavior back. It seems to me that, given your tool's 0.10 version number, you have the freedom to rationalize this and make all modes interactive, and skip the flag. If one wants unconditional push/pop, use regular Fossil.

Also, "get" in fnc vs "apply" in Fossil is confusing. You should use the same verbs Fossil does to reduce friction.

In fnc, it's just fossil stash. I proposed the --interactive flag
for fossil(1) given the stash command's semantics in Fossil. I don't
have that burden in fnc so prefer making fnc stash the interactive
stash as I don't plan on having a "normal" stash op in fnc—that's what
Fossil is for. This post is an RFC for the interactive stash in Fossil,
I'm happy with the stash semantics in fnc. We differ from Fossil in
several ways, and there's no plan for consistent naming or behaviour with
Fossil's interfaces.

As for putting this into Fossil proper, if my recollection of a general objection to adding ncurses things to Fossil is correct, then I say leave this feature in fnc. I don't see why you'd do this sort of thing any other way.

I don't make this proposal with the intention to introduce a curses
dependency; output would be dumped to stdout. The UI would pretty much
be the same as Git's git add -p; except to stash selected hunks—not
stage them.

I'll be happy to add a mention for this to the gitusers doc when you've got the feature stable at the function and UI levels.

The current interface is pretty stable in fnc, except I'm thinking about
adding a (s)plit this hunk option. But I'd like more real world use
before declaring it robust. I've been using it on half a dozen repos for
a ~week or so now with no problems, but more diverse (ab)use is needed.

ETA: I forgot to mention, given libfossil's aliases, we can add
apply as an alias to fnc stash get, which I'll do.

(3) By Daniel Dumitriu (danield) on 2022-04-28 15:02:13 in reply to 1 [link] [source]

I'd like to see this, at least in order to test it.

As for the Warren's ncurses objection: I don't think ncurses and its capabilities are important here, after all, hunks can be presented on stdout, as Mark said. Or am I missing something?

(6) By mark on 2022-04-29 06:09:50 in reply to 3 [link] [source]

I don't think ncurses and its capabilities are important here, after all, hunks can be presented on stdout, as Mark said. Or am I missing something?

No, you're right. No curses dep needed.

(4) By John Rouillard (rouilj) on 2022-04-28 16:05:45 in reply to 1 [link] [source]

I like this idea. Doing an interactive stash is supported by the fsl fossil wrapper as well. I would love to see it in fossil proper.

fsl doesn't use a curses interface, it's all text. For example:

$ fossil diff --numstat html/form_issue.html
        19         18 html/form_issue.html
        19         18 TOTAL over 1 changed files

$ fossil rstash save -m "test interactve stash" html/form_issue.html
examine file 'html/form_issue.html' [1/1]? [Ynsfdaq?] ?
y - yes, record this change
n - no, do not record this change
s - skip remaining changes to this file
f - record remaining changes to this file
d - done, skip remaining changes and files
a - record all remaining changes to all remaining files
q - quit, record no changes
? - help, show this message
examine file 'html/form_issue.html' [1/1]? [Ynsfdaq?] y
@@ -167,4 +167,4 @@
                 class="wide">Depended on by:</label>
-         <div class="s1" tal:define="rdepf
-                                     python:db.issue.filter(filterspec={'dependson':context.id})"
+         <span class="revlinks" tal:define="rdepf
+               python:db.issue.filter(filterspec={'dependson':context.id})"
               tal:condition="not:InBatchUpdate">

record hunk [1/10]? [Ynsfdaq?] y
@@ -180,3 +180,3 @@
            <tal:span tal:condition="not:rdepf">&nbsp;</tal:span>
-         </div>
+         </span>
        </tal:block>

record hunk [2/10]? [Ynsfdaq?] y
@@ -214,3 +214,3 @@
                 class="wide">Grouped by:</label>
-         <div class="s1" tal:define="rgroupf
+         <span class="revlinks" tal:define="rgroupf
                                      python:db.issue.filter(

record hunk [3/10]? [Ynsfdaq?] y
@@ -228,3 +228,3 @@
            <tal:span tal:condition="not:rgroupf">&nbsp;</tal:span>
-         </div>
+         </span>
        </tal:block>

record hunk [4/10]? [Ynsfdaq?] s
REVERT   html/form_issue.html

$ fossil diff --numstat html/form_issue.html
        15         14 html/form_issue.html
        15         14 TOTAL over 1 changed files

$ fossil stash pop
MERGE html/form_issue.html
 "fossil undo" is available to undo changes to the working checkout.
$ fossil diff --numstat html/form_issue.html
        19         18 html/form_issue.html
        19         18 TOTAL over 1 changed files

the recorded hunks are placed in the stash and can be reapplied. You can also run this multiple times to create multiple stashes and manipulate the stashes as needed.

(7.1) By mark on 2022-04-29 06:19:11 edited from 7.0 in reply to 4 [link] [source]

I like this idea. Doing an interactive stash is supported by the fsl fossil wrapper as well. I would love to see it in fossil proper.

I would love to see it in Fossil too. I think it's a useful tool that
would benefit Fossil users. I've never used fsl; I'll check it out.
Thanks for mentioning it!

fsl doesn't use a curses interface, it's all text.

Yes, this is what I have in mind for Fossil too.

It's worth noting that it will be a fair bit of code, but mostly novel.
Very little churn to the existing codebase, I suspect.

ETA: Although, come to think of it, there's another way to implement it
by adding some functionality to the diff builder. Hmmm. I might explore
that in fnc first to see how viable it is, and if it's any better.