vim-fugitive
vim-fugitive copied to clipboard
Stage visual selection (add -p)
It would be great if fugitive could provide a mapping to stage the current visual selection of a file.
Obviously there is no straight forward way to achieve this. The only approach I could find is something that I found on stackoverflow and it involves fiddling around with the index behind git add's back (http://stackoverflow.com/a/2785039/457853):
#!/bin/sh
start_line=$1
end_line=$2
path=$3
mode=$(git ls-files -s $path | awk '{print $1}')
blob_id=$(
(
head -n $(expr $start_line - 1) $path
cat
tail -n +$(expr $end_line + 1) $path
) | git hash-object -w --stdin
)
exec git update-index --cacheinfo $mode $blob_id $path
Maybe there are other ways to achieve the same? In either case it would be a feature that I would love to see.
Won't that only work if there have been no line additions or deletions in the file?
I don't know if I'm misunderstanding something, but in the screencasts mentioned in README.md I learned, that in :Gdiff
you'd just :diffput
to the index version of the file and then save that index, leading to the :diffputed
changes beeing staged, pretty straightforward imo. I'm doing it always like this as sometimes I can do it even more specific than with plain add -p
(some chunks are not splittable, but perhaps I'm missing something on the git side here).
A function for directly staging visual-selected lines (without the need to :Gdiff
etc.) would be nice though.
Was just looking if this is possible and I think it would be a quite useful feature as well :+1:
You can achieve this using :Gdiff
with :diffput
and :diffget
- Fire up
:Gdiff
- Visually select the change/line you want to stage.
:diffput
- Profit
From, this vimcasts episode: http://vimcasts.org/episodes/fugitive-vim-working-with-the-git-index/
Awesome! Thanks :+1:
I would also be very happy if such a feature was added. Using :Gdiff works but is a little clunky.
Using :Gdiff works but is a little clunky.
Could you elaborate on “clunky”, please?
@mcepl the workflow is:
- mark lines to be staged
- use diffget/put or anything to copy over to index file (which one was the index again?)
- save the index file
This feels overcomplicated when I just want to "stage these lines". It is already possible to stage the current file with :Gwrite
so a :'<,'>Gwrite
to stage the current selection feels kind of natural.
This feels overcomplicated when I just want to "stage these lines". It is already possible to stage the current file with :Gwrite so a :'<,'>Gwrite to stage the current selection feels kind of natural.
I kind of like the additional security in knowing that before I write Gwrite
nothing actually gets changed.
The GitGutter plugin has this feature:
https://github.com/airblade/vim-gitgutter#hunks
very useful IMHO.
Would like this too
Hi. Do you have any updates on this feature?
BTW thanks a lot for your awesome plugins!
My update is I asked a question 6 years ago and nobody answered it.
Won't that only work if there have been no line additions or deletions in the file?
I see your point there. I have tried the script on deletion and it doesn't work.
The workflow using diffput on :Gdiff
on the other hand is quite simple to use.
It would certainly be possible to filter the lines in git diff
to only include the provided range and feed the result to git apply --index
. It'd still be kind of weird that we're writing the entire work tree file but only part of the index file, but I guess that's what people would naturally expect to happen.
As I understood, the Gwrite
will stage the whole work tree file and git apply --index
only change part of the index file. What would be the consequences if we do this in your opinion?
If the file is already written to disk, the way to do this is to git diff
the file, modify that patch to exclude lines outside the range by looking at hunk headers and doing some counting, and git apply --cached
it. We do something similar for inline diffs in the :Gstatus
window, although "excluding lines outside the range" means something very different there. If someone implements the `"modify that patch" bit, I can probably glue the rest together.
If the file has unwritten changes, that raises a bunch of questions, but I'd be fine to accept "write the entire file to the work tree first" as the path of least resistance.
@sondnm The consequence I was alluding to is that someone might expect :1,2Gwrite
to behave like :1,2write
, effectively deleting all but the first 2 lines. But I've come to the decision that's silly and we can ignore it.
modify that patch to exclude lines outside the range by looking at hunk headers and doing some counting
maybe we could use external utility for that: Quilt (software)
I will not accept an external dependency to avoid "looking at hunk headers and doing some counting". This isn't hard, it's just tedious.
Makes sense. Maybe we could borrow the code from it then.
I guess what is missing here is on the GStatus window when i open the file with enter i just enter a the fugitive diff mode and then stage the chunks from them?
As a current workout around just press I on the status file right?
I guess what is missing here is on the GStatus window when i open the file with enter i just enter a the fugitive diff mode and then stage the chunks from them?
You can do this in one step by pressing dd
on the file.
As a current workout around just press I on the status file right?
That's less of a workaround and more of an alternative workflow, and as far as alternative workflows go, I'd sooner recommend pressing =
.
@tpope There's a real UX issue hidden behind this issue, and that is if you have the Gstatus open, you press enter, you go to the file to review the changes, you review and choose to stage specific hunks with diffput or whatever, then everything ok so far.
BUT
then you go to the status window to proceed with the hunks in the next file. The moment you press enter, the window with the staged version goes away, and you have to type again :Gdiff.
This destroys the overall flow which you actually have with git add -pv.
I'd rather take a step back and look at the flow in its entirety and make fugitive provide added value where it shines.
For me, that is breaking out of the linear flow which I have in the terminal, for instance seeing the git status and the code at the same time.
Also sometimes, I simply know what I want to stage, once I'm in a file and I see the whole context (thanks fugitive), doing :Gdiff is just additional fluff.
Staging the selected range would improve the workflow immensly without giving up on the advantages of using fugitive.
Think about it for a moment, how many keystrokes does a git add -pv user invest? The goal of fugitive should be to reduce that count (which it does naturally, because it breaks out of the linearity), but then you throw a compulsory :Gdiff in there and by doing so you throw away all the hanging fruit.
Yet, I still appreciate the nonlinearity of fugitive, it would just speed me up if it would play along with the rest of the flow.
@tpope There's a real UX issue hidden behind this issue, and that is if you have the Gstatus open, you press enter, you go to the file to review the changes, you review and choose to stage specific hunks with diffput or whatever, then everything ok so far.
BUT
then you go to the status window to proceed with the hunks in the next file. The moment you press enter, the window with the staged version goes away, and you have to type again :Gdiff.
You can do this in one step by pressing dd
on the file.
You can do this in one step by pressing dd
on the file.
You can do this in one step by pressing dd
on the file.
You can do this in one step by pressing dd
on the file.
You can do this in one step by pressing dd
on the file.
There, now hopefully everyone will actually see it.
Staging the selected range would improve the workflow immensly without giving up on the advantages of using fugitive.
I've already given advice on what's needed to implement it, so it's hard to read this as anything other than nagging me to do it myself. That will get you nowhere.
Side-note: in the Gstatus window, you can press =
on a file to show all changes, do a line selection shift-v
in there, and press s
to stage just those lines (even they are a subset of a hunk). This is quite a nice final-review flow, using gU
and then cntrl-N
/ cntrl-P
and toggling =
, and staging everything from within the Gstatus window.
Ya lo lograron
Estoy esperando ha que acaben de desinflar mi contenido para irme a mi otro cel y kmplementar más candados en este perfil jajaja si lo que puse aki es algo básico kieren algo más difícil?