git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Multiple indices / staging areas
@ 2024-01-30  3:47 Jacek Lipiec
  2024-02-02  8:35 ` Junio C Hamano
  0 siblings, 1 reply; 2+ messages in thread
From: Jacek Lipiec @ 2024-01-30  3:47 UTC (permalink / raw)
  To: git

Hello,
I am thinking about extending the current index mechanism, and I wish
to ask for feedback if this would be something that you would be
interested in. Please note, I have no prior git development
experience.

The main idea is to mirror the "changelist" functionality found in
IntelliJ IDE's (https://www.jetbrains.com/help/idea/managing-changelists.html).
Namely, at each given moment you can create a "changelist"/separate
index to which you can move hunks to. Such changelists are named, and
optionally have a (default) commit message.
This allows for an easy way to split current changes into separate
commits, to have clean and atomic work units committed; while seeing
the combined changes in the worktree; as well as having a
conceptual/logical separation for changes

Scenario: I am introducing a new functionality. Changes are
conceptually separate, but work together. i.e. new version of package
& using the new functionality from the package.
Scenario 2: I am not yet sure about what needs to be done, so I am
sketching in code. Some changes will be of linting nature, some will
introduce code, some will be an "ad-hoc fix".

What we can do with the current flow:
* Commit/amend/fixup. This works best when one has prior knowledge of
what needs to be done, i.e. bumping versions then using the
functionality. Problems arise when the code is "living", as such you
need to fixup commits in the local branch, which can lead to
conflicts. Another issue is that if you wish to commit small change
(i.e. a fix for a linter) you need to juggle the staging area. (This
is my current flow in the vanilla git. It can become clunky if you,
like me, sketch the solution in the code)
* git worktree. While this functionality is the closest to what I am
proposing, it does not allow for easy transfer of hunks, nor it allows
for working with all the changes in the same worktree at the same
time.
* branches. This again does not allow us to see all the changes at the
same time.

The idea for the implementation would be as follows, and should
hopefully introduce no change to the existing flow.

1) Design

1.1) New indices file
We add a new file in the $GIT_DIR, called `indices`. This is a map
file that will MUST have at least one entry. Index entry MUST have a
name. Index entries COULD have default commit message
Example:
```.git/indices
selected=1 # maps to .git/index.1
#  translates to .git/index.0
index[0].name=Default
#  translates to .git/index.1
index[1].name=Add named index
#  translates to .git/index.2
index[2].name=Wip
index[2].message=Add named index\n\nThis is a longer description
```
The "selected" index is in two places - one is `index` and the other
is based on the selected entry; so following example, `index.1`. The
best way to keep them synced would be to symlink them, though this
would introduce FS dependency. Synchronized copy would work as well.
Renames could work, but there would be IMO high risk of losing changes
from the index due to a mistake.

This way, the existing index file format remains unchanged; and all
new functionality can be handled via the new `indices` file; due to
that all existing code should work without an issue.
I see a potential problem of two indices overlapping (i.e. index
changed via older git, or other tool) - in this case I would
transparently correct other indices, treating selected index as the
source of truth. This would imply that software not aware of the
indices would see the changes in the not-selected index as unstaged.
The second issue is the split index, as I know nothing about it, yet
it might require changes.

1.2) Commands
A git index create <name> [-m|--message <message>]
A git index delete <name>
A git index switch <name>
A git index update <name> [-m|--message <message>] [-n|--name <new name>]
M git add [-I|--index <index name>]
M git diff [-I|--index <index name>]

2) Example workflows
2.1) Working with indices/non interactive add
git index create "wip" --message="This is a default commit message" #
We have a new index, but the default one is selected
touch {example|example2|example3}
git add example # Added to the "current"/"default" index, by default 0
git index switch "wip"
git add example2 # Added to the "wip"/ index, with id of 1
git add example3 --index=default # Added to the "current"/"default" index,
git commit # commit message="This is a default commit message"
# At this point, index.1 (wip) is empty, but selected. We can commit
another index
git commit --index=default -m "This is a commit message for the default index"

2.2) Status
> git status
On branch main
Selected index: wip
Changes to be committed (wip):
  (use "git restore --staged <file>..." to unstage)
        modified:   example

Changes staged for commit (default)
  (use "git restore --index=default --staged <file>..." to unstage)
        modified:   example

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   example

2.3) Git add (interactive)
> git add --interactive # details omitted for brevity
-Example change
+Example change 2
(1/1) Stage this hunk to wip [y,n,q,a,d,e,i,?]?
> ?
i - change the current index

2.4) Remove index
> git index remove # removes current, all staged goes to the "default" branch/index 0
> git index remove wip # removes wip, all staged goes to the default branch/index 0
> git index switch default
> git index remove # Does nothing...
> git index rename default "WIP" # index[0].name=WIP
> git index remove # renames default -> index[0].name=Default
...

I am open for the feedback/questions, or early go/nogo.

Jacek Lipiec

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Multiple indices / staging areas
  2024-01-30  3:47 Multiple indices / staging areas Jacek Lipiec
@ 2024-02-02  8:35 ` Junio C Hamano
  0 siblings, 0 replies; 2+ messages in thread
From: Junio C Hamano @ 2024-02-02  8:35 UTC (permalink / raw)
  To: Jacek Lipiec; +Cc: git

Jacek Lipiec <jacek.lipiec.bc@gmail.com> writes:

> I am open for the feedback/questions, or early go/nogo.

Given that even having one index between the committed history and
the working tree files seems to add cognitive load to new users, I
am not very enthused to hear that we may be able to add an arbitrary
number of them, and more importantly, I don't quite see what real
world problems the additional complexities (most of them are probably
not accounted for in the sketch we saw and yet to be discovered) are
solving.

But I'll wait before sending this response for a few days and keep
it in my outbox.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2024-02-02  8:36 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-01-30  3:47 Multiple indices / staging areas Jacek Lipiec
2024-02-02  8:35 ` Junio C Hamano

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).