1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-11-05 08:47:56 +01:00
Commit graph

97 commits

Author SHA1 Message Date
Jeff King
01143847db add--interactive: allow custom diff highlighting programs
The patch hunk selector of add--interactive knows how ask
git for colorized diffs, and correlate them with the
uncolored diffs we apply. But there's not any way for
somebody who uses a diff-filter tool like contrib's
diff-highlight to see their normal highlighting.

This patch lets users define an arbitrary shell command to
pipe the colorized diff through. The exact output shouldn't
matter (since we just show the result to humans) as long as
it is line-compatible with the original diff (so that
hunk-splitting can split the colorized version, too).

I left two minor issues with the new system that I don't
think are worth fixing right now, but could be done later:

  1. We only filter colorized diffs. Theoretically a user
     could want to filter a non-colorized diff, but I find
     it unlikely in practice. Users who are doing things
     like diff-highlighting are likely to want color, too.

  2. add--interactive will re-colorize a diff which has been
     hand-edited, but it won't have run through the filter.
     Fixing this is conceptually easy (just pipe the diff
     through the filter), but practically hard to do without
     using tempfiles (it would need to feed data to and read
     the result from the filter without deadlocking; this
     raises portability questions with respect to Windows).

I've punted on both issues for now, and if somebody really
cares later, they can do a patch on top.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-02-28 10:53:54 -08:00
Junio C Hamano
c1fa3e21bc Merge branch 'ak/add-i-empty-candidates'
The interactive "show a list and let the user choose from it"
interface "add -i" used showed and prompted to the user even when
the candidate list was empty, against which the only "choice" the
user could have made was to choose nothing.

* ak/add-i-empty-candidates:
  add -i: return from list_and_choose if there is no candidate
2015-02-17 10:15:20 -08:00
Alexander Kuleshov
a9c4641df7 add -i: return from list_and_choose if there is no candidate
The list_and_choose() helper is given a prompt and a list, asks the
user to make selection from the list, and then returns a list of
items chosen.  Even when it is given an empty list as the original
candidate set to choose from, it gave a prompt to the user, who can
only say "I am done choosing".

Return an empty result when the input is an empty list without
bothering the user.  The existing caller must already have a logic
to say "Nothing to do" or an equivalent when the returned list is
empty (i.e. the user chose to select nothing) if it is necessary, so
no change to the callers is necessary.

This fixes the case where "add untracked" is asked in "git add -i"
and there is no untracked files in the working tree.  We used to give
an empty list of files to choose from with a prompt, but with this
change, we no longer do.

Signed-off-by: Alexander Kuleshov <kuleshovmail@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-01-22 14:44:36 -08:00
Jeff King
a8bec7abcc add--interactive: leave main loop on read error
The main hunk loop for add--interactive will loop if it does
not get a known input. This is a good thing if the user
typed some invalid input. However, if we have an
uncorrectable read error, we'll end up looping infinitely.
We can fix this by noticing read errors (i.e., <STDIN>
returns undef) and breaking out of the loop.

One easy way to trigger this is if you have an editor that
does not take over the terminal (e.g., one that spawns a
window in an existing process and waits), start the editor
with the hunk-edit command, and hit ^C to send SIGINT. The
editor process dies due to SIGINT, but the perl
add--interactive process does not (perl suspends SIGINT for
the duration of our system() call).

We return to the main loop, but further reads from stdin
don't work. The SIGINT _also_ killed our parent git process,
which orphans our process group, meaning that further reads
from the terminal will always fail. We loop infinitely,
getting EIO on each read.

Note that there are several other spots where we read from
stdin, too. However, in each of those cases, we do something
sane when the read returns undef (breaking out of the loop,
taking the input as "no", etc). They don't need similar
treatment.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-15 10:12:20 -08:00
Junio C Hamano
d59c12d7ad Merge branch 'jl/nor-or-nand-and'
Eradicate mistaken use of "nor" (that is, essentially "nor" used
not in "neither A nor B" ;-)) from in-code comments, command output
strings, and documentations.

* jl/nor-or-nand-and:
  code and test: fix misuses of "nor"
  comments: fix misuses of "nor"
  contrib: fix misuses of "nor"
  Documentation: fix misuses of "nor"
2014-04-08 12:00:28 -07:00
Justin Lebar
235e8d5914 code and test: fix misuses of "nor"
Signed-off-by: Justin Lebar <jlebar@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-03-31 15:29:33 -07:00
Simon Ruderich
b294097bc6 git-add--interactive: warn if module for interactive.singlekey is missing
Suggested-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Simon Ruderich <simon@ruderich.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-03-03 14:11:18 -08:00
Jeff King
954312a3ff add-interactive: handle unborn branch in patch mode
The list_modified function already knows how to handle an
unborn branch by diffing against the empty tree. However,
the diff we perform to get the actual hunks does not. Let's
use the same logic for both diffs.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-10-25 14:54:17 -07:00
Johannes Sixt
df17e77c0a add--interactive: fix external command invocation on Windows
Back in 21e9757e (Hack git-add--interactive to make it work with
ActiveState Perl, 2007-08-01), the invocation of external commands was
changed to use qx{} on Windows. The rationale was that the command
interpreter on Windows is not a POSIX shell, but rather Windows's CMD.
That patch was wrong to include 'msys' in the check whether to use qx{}
or not: 'msys' identifies MSYS perl as shipped with Git for Windows,
which does not need the special treatment; qx{} should be used only with
ActiveState perl, which is identified by 'MSWin32'.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-09-04 10:35:25 -07:00
Junio C Hamano
e5c2909782 add -i: add extra options at the right place in "diff" command line
Appending "--diff-algorithm=histogram" at the end of canned command
line for various modes of "diff" is correct for most of them but not
for "stash" that has a non-option already wired in, like so:

	'stash' => {
		DIFF => 'diff-index -p HEAD',

Appending an extra option after non-option may happen to work due to
overly lax command line parser, but that is not something we should
rely on.  Instead, splice in the extra argument immediately after the
command name (i.e. 'diff-index', 'diff-files', etc.).

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-06-23 13:39:39 -07:00
John Keeping
2cc0f53b53 add--interactive: respect diff.algorithm
When staging hunks interactively it is sometimes useful to use an
alternative diff algorithm which splits the changes into hunks in a more
logical manner.  This is not possible because the plumbing commands
called by add--interactive ignore the "diff.algorithm" configuration
option (as they should).

Since add--interactive is a porcelain command it should respect this
configuration variable.  To do this, make it read diff.algorithm and
pass its value to the underlying diff-index and diff-files invocations.

At this point, do not add options to "git add", "git reset" or "git
checkout" (all of which can call git-add--interactive).  If a user
wants to override the value on the command line they can use:

	git -c diff.algorithm=$ALGO ...

Signed-off-by: John Keeping <john@keeping.me.uk>
Reviewed-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-06-12 13:41:19 -07:00
Stefano Lattarini
41ccfdd9c9 Correct common spelling mistakes in comments and tests
Most of these were found using Lucas De Marchi's codespell tool.

Signed-off-by: Stefano Lattarini <stefano.lattarini@gmail.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Acked-by: Matthieu Moy <Matthieu.Moy@imag.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-04-12 13:38:40 -07:00
Thomas Badie
70969f775d git-add--interactive.perl: Remove two unused variables
The patch 8f0bef6 refactored this script and made the variable $fh
unneeded in subs diff_applies and patch_update_file, but forgot to
remove them.

Signed-off-by: Thomas Badie <badie@lrde.epita.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-06-25 10:06:09 -07:00
Jeff King
4066bd6797 add--interactive: ignore unmerged entries in patch mode
When "add -p" sees an unmerged entry, it shows the combined
diff and then immediately skips the hunk. This can be
confusing in a variety of ways, depending on whether there
are other changes to stage (in which case you get the
superfluous combined diff output in between other hunks) or
not (in which case you get the combined diff and the program
exits immediately, rather than seeing "No changes").

The current behavior was not planned, and is just what the
implementation happens to do. Instead, let's explicitly
remove unmerged entries from our list of modified files, and
print a warning that we are ignoring them.

We can cheaply find which entries are unmerged by adding
"--raw" output to the "diff-files --numstat" we already run.
There is one non-obvious thing we must change when parsing
this combined output. Before this patch, when we saw a
numstat line for a file that did not have index changes, we
would create a new record with 'unchanged' in the 'INDEX'
field.  Because "--raw" comes before "--numstat", we must
move this special-case down to the raw-line case (and it is
sufficient to move it rather than handle it in both places,
since any file which has a --numstat will also have a --raw
entry).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-04-05 09:01:03 -07:00
Thomas Rast
b5cc003253 add -i: ignore terminal escape sequences
On the author's terminal, the up-arrow input sequence is ^[[A, and
thus fat-fingering an up-arrow into 'git checkout -p' is quite
dangerous: git-add--interactive.perl will ignore the ^[ and [
characters and happily treat A as "discard everything".

As a band-aid fix, use Term::Cap to get all terminal capabilities.
Then use the heuristic that any capability value that starts with ^[
(i.e., \e in perl) must be a key input sequence.  Finally, given an
input that starts with ^[, read more characters until we have read a
full escape sequence, then return that to the caller.  We use a
timeout of 0.5 seconds on the subsequent reads to avoid getting stuck
if the user actually input a lone ^[.

Since none of the currently recognized keys start with ^[, the net
result is that the sequence as a whole will be ignored and the help
displayed.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-05-17 20:44:17 -07:00
Junio C Hamano
933e44d3a0 "add -p": work-around an old laziness that does not coalesce hunks
Since 0beee4c (git-add--interactive: remove hunk coalescing, 2008-07-02),
"git add--interactive" behaves lazily and passes overlapping hunks to the
underlying "git apply" without coalescing.  This was partially corrected
by 7a26e65 (its partial revert, 2009-05-16), but overlapping hunks are
still passed when the patch is edited.

Teach "git apply" the --allow-overlap option that disables a safety
feature that avoids misapplication of patches by not applying patches
to overlapping hunks, and pass this option form "add -p" codepath.

Do not even advertise the option, as this is merely a workaround, and the
correct fix is to make "add -p" correctly coalesce adjacent patch hunks.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-04-29 15:27:59 -07:00
Junio C Hamano
9dce832354 add--interactive.perl: factor out repeated --recount option
Depending on the direction and the target of patch application, we would
need to pass --cached and --reverse to underlying "git apply".  Also we
only pass --check when we are not applying but just checking.

But we always pass --recount since 8cbd431 (git-add--interactive: replace
hunk recounting with apply --recount, 2008-07-02).  Instead of repeating
the same --recount over and over again, move it to a single place that
actually runs the command, namely, "run_git_apply" subroutine.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-04-29 15:27:59 -07:00
Junio C Hamano
f5ea3f2bb3 add -p: 'q' should really quit
The "quit" command was added in 9a7a1e0 (git add -p: new "quit" command at
the prompt, 2009-04-10) to allow the user to say that hunks other than
what have already been chosen are undesirable, and exit the interactive
loop immediately.  It forgot that there may be an undecided hunk before
the current one.  In such a case, the interactive loop still goes back to
the beginning.

Clear all the USE bit for undecided hunks and exit the loop.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-04-29 15:25:03 -07:00
Junio C Hamano
1aa6583cc2 Merge branch 'jl/add-p-reverse-message'
* jl/add-p-reverse-message:
  Correct help blurb in checkout -p and friends
2010-11-29 17:52:34 -08:00
Jonathan "Duke" Leto
7b8c705188 Correct help blurb in checkout -p and friends
When git checkout -p from the index or HEAD is run in edit mode, the
help message about removing '-' and '+' lines was backwards. Because it
is reverse applying the patch, the meanings of '-' and '+' are reversed.

Signed-off-by: Jonathan "Duke" Leto <jonathan@leto.net>
Acked-by: Thomas Rast <trast@student.ethz.ch>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-10-28 15:28:39 -07:00
Ævar Arnfjörð Bjarmason
3328acedc6 perl: use "use warnings" instead of -w
Change the Perl scripts to turn on lexical warnings instead of setting
the global $^W variable via the -w switch.

The -w sets warnings for all code that interpreter runs, while "use
warnings" is lexically scoped. The former is probably not what the
authors wanted.

As an auxiliary benefit it's now possible to build Git with:

    PERL_PATH='/usr/bin/env perl'

Which would previously result in failures, since "#!/usr/bin/env perl -w"
doesn't work as a shebang.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-09-27 12:37:56 -07:00
Ævar Arnfjörð Bjarmason
d48b284183 perl: bump the required Perl version to 5.8 from 5.6.[21]
Formalize our dependency on perl 5.8, bumped from 5.6.[12]. We already
used the three-arg form of open() which was introduced in 5.6.1, but
t/t9700/test.pl explicitly depended on 5.6.2.

However git-add--interactive.pl has been failing on the 5.6 line since
it was introduced in v1.5.0-rc0~12^2~2 back in 2006 due to this open
syntax:

    sub run_cmd_pipe {
           my $fh = undef;
           open($fh, '-|', @_) or die;
           return <$fh>;
    }

Which when executed dies on "Can't use an undefined value as
filehandle reference". Several of our tests also fail on 5.6 (even
more when compiled with NO_PERL_MAKEMAKER=1):

    t2016-checkout-patch.sh
    t3904-stash-patch.sh
    t3701-add-interactive.sh
    t7105-reset-patch.sh
    t7501-commit.sh
    t9700-perl-git.sh

Our code is bitrotting on 5.6 with no-one interested in fixing it, and
pinning us to such an ancient release of Perl is keeping us from using
useful features introduced in the 5.8 release.

The 5.6 series is now over 10 years old, and the 5.6.2 maintenance
release almost 7. 5.8 on the other hand is more than 8 years old.

All the modern Unix-like operating systems have now upgraded to it or
a later version, and 5.8 packages are available for old IRIX, AIX
Solaris and Tru64 systems.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Acked-by: Tor Arntsen <tor@spacetec.no>
Acked-by: Randal L. Schwartz <merlyn@stonehenge.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-09-27 12:37:41 -07:00
Jonathan Nieder
74e42ce122 add-interactive: Clarify “remaining hunks in the file”
The "a" and "d" commands to ‘add --patch’ (accept/reject rest of file)
interact with "j", "g", and "/" (skip some hunks) in a perhaps
confusing way: after accepting or rejecting all _later_ hunks in the
file, they return to the earlier, skipped hunks and prompt the user
about them again.

This behavior can be very useful in practice.  One can still accept or
reject _all_ undecided hunks in a file by using the "g" command to
move to hunk #1 first.

Reported-by: Frédéric Brière <fbriere@fbriere.net>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-06-13 10:05:02 -07:00
Junio C Hamano
9382587467 Merge branch 'jk/maint-add--interactive-delete'
* jk/maint-add--interactive-delete:
  add-interactive: fix bogus diff header line ordering
2010-03-07 12:47:14 -08:00
Jeff King
e1327ed5fb add-interactive: fix bogus diff header line ordering
When we look at a patch for adding hunks interactively, we
first split it into a header and a list of hunks. Some of
the header lines, such as mode changes and deletion, however,
become their own selectable hunks. Later when we reassemble
the patch, we simply concatenate the header and the selected
hunks. This leads to patches like this:

  diff --git a/file b/file
  index d95f3ad..0000000
  --- a/file
  +++ /dev/null
  deleted file mode 100644
  @@ -1 +0,0 @@
  -content

Notice how the deletion comes _after_ the ---/+++ lines,
when it should come before.

In many cases, we can get away with this as git-apply
accepts the slightly bogus input. However, in the specific
case of a deletion line that is being applied via "apply
-R", this malformed patch triggers an assert in git-apply.
This comes up when discarding a deletion via "git checkout
-p".

Rather than try to make git-apply accept our odd input,
let's just reassemble the patch in the correct order.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-02-22 19:23:49 -08:00
Junio C Hamano
ff86bdd5ca Merge branch 'maint'
* maint:
  add-interactive: fix deletion of non-empty files
  pull: clarify advice for the unconfigured error case
2009-12-08 22:47:09 -08:00
Junio C Hamano
a876433c5f Merge branch 'jk/maint-add-p-delete-fix' into maint
* jk/maint-add-p-delete-fix:
  add-interactive: fix deletion of non-empty files
2009-12-08 22:37:50 -08:00
Jeff King
8947fdd598 add-interactive: fix deletion of non-empty files
Commit 24ab81a fixed the deletion of empty files, but broke
deletion of non-empty files. The approach it took was to
factor out the "deleted" line from the patch header into its
own hunk, the same way we do for mode changes. However,
unlike mode changes, we only showed the special "delete this
file" hunk if there were no other hunks. Otherwise, the user
would annoyingly be presented with _two_ hunks: one for
deleting the file and one for deleting the content.

This meant that in the non-empty case, we forgot about the
deleted line entirely, and we submitted a bogus patch to
git-apply (with "/dev/null" as the destination file, but not
marked as a deletion).

Instead, this patch combines the file deletion hunk and the
content deletion hunk (if there is one) into a single
deletion hunk which is either staged or not.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-12-07 23:52:46 -08:00
Junio C Hamano
376f39fbea Merge branch 'jn/editor-pager'
* jn/editor-pager:
  Provide a build time default-pager setting
  Provide a build time default-editor setting
  am -i, git-svn: use "git var GIT_PAGER"
  add -i, send-email, svn, p4, etc: use "git var GIT_EDITOR"
  Teach git var about GIT_PAGER
  Teach git var about GIT_EDITOR
  Suppress warnings from "git var -l"
  Do not use VISUAL editor on dumb terminals
  Handle more shell metacharacters in editor names
2009-11-20 23:48:52 -08:00
Junio C Hamano
5e9cb8666b Merge branch 'jk/maint-add-p-empty' into maint
* jk/maint-add-p-empty:
  add-interactive: handle deletion of empty files
2009-11-16 00:02:44 -08:00
Junio C Hamano
3176bd0b0d Merge branch 'jk/maint-add-p-empty'
* jk/maint-add-p-empty:
  add-interactive: handle deletion of empty files
2009-11-15 16:40:46 -08:00
Jonathan Nieder
b4479f0747 add -i, send-email, svn, p4, etc: use "git var GIT_EDITOR"
Use the new "git var GIT_EDITOR" feature to decide what editor to
use, instead of duplicating its logic elsewhere.  This should make
the behavior of commands in edge cases (e.g., editor names with
spaces) a little more consistent.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-11-13 12:20:50 -08:00
Jeff King
24ab81ae4d add-interactive: handle deletion of empty files
Usually we show deletion as a big hunk deleting all of the
file's text. However, for files with no content, the diff
shows just the 'deleted file mode ...' line. This patch
cause "add -p" (and related commands) to recognize that line
and explicitly ask about deleting the file.

We only add the "stage this deletion" hunk for empty files,
since other files will already ask about the big content
deletion hunk. We could also change those files to simply
display "stage this deletion", but showing the actual
deleted content is probably what an interactive user wants.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-10-27 23:19:04 -07:00
Junio C Hamano
70ed433c2b Merge branch 'pv/maint-add-p-no-exclude' into maint
* pv/maint-add-p-no-exclude:
  git-add--interactive: never skip files included in index
2009-10-23 22:29:19 -07:00
Junio C Hamano
c274db7057 Merge branch 'pv/maint-add-p-no-exclude'
* pv/maint-add-p-no-exclude:
  git-add--interactive: never skip files included in index
2009-10-14 16:13:20 -07:00
Pauli Virtanen
b145b211ba git-add--interactive: never skip files included in index
Make "git add -p" to not skip files that are in index even if they are
excluded (by .gitignore etc.). This fixes the contradictory behavior
that "git status" and "git commit -a" listed such files as modified, but
"git add -p FILENAME" ignored them.

Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-10-10 14:56:13 -07:00
Junio C Hamano
54f0bdc811 Merge branch 'tr/reset-checkout-patch'
* tr/reset-checkout-patch:
  stash: simplify defaulting to "save" and reject unknown options
  Make test case number unique
  tests: disable interactive hunk selection tests if perl is not available
  DWIM 'git stash save -p' for 'git stash -p'
  Implement 'git stash save --patch'
  Implement 'git checkout --patch'
  Implement 'git reset --patch'
  builtin-add: refactor the meat of interactive_add()
  Add a small patch-mode testing library
  git-apply--interactive: Refactor patch mode code
  Make 'git stash -k' a short form for 'git stash save --keep-index'
2009-09-07 15:24:38 -07:00
Junio C Hamano
9e4a90ba19 Merge branch 'tr/maint-1.6.3-add-p-modeonly-fix' into maint-1.6.3
* tr/maint-1.6.3-add-p-modeonly-fix:
  add -p: do not attempt to coalesce mode changes
  git add -p: demonstrate failure when staging both mode and hunk
2009-08-26 11:22:00 -07:00
Junio C Hamano
09ba7b2d9f Merge branch 'tr/maint-1.6.3-add-p-modeonly-fix'
* tr/maint-1.6.3-add-p-modeonly-fix:
  add -p: do not attempt to coalesce mode changes
  git add -p: demonstrate failure when staging both mode and hunk
2009-08-18 23:32:58 -07:00
Thomas Rast
dda1f2a5c3 Implement 'git stash save --patch'
This adds a hunk-based mode to git-stash.  You can select hunks from
the difference between HEAD and worktree, and git-stash will build a
stash that reflects these changes.  The index state of the stash is
the same as your current index, and we also let --patch imply
--keep-index.

Note that because the selected hunks are rolled back from the worktree
but not the index, the resulting state may appear somewhat confusing
if you had also staged these changes.  This is not entirely
satisfactory, but due to the way stashes are applied, other solutions
would require a change to the stash format.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-08-15 15:19:31 -07:00
Thomas Rast
4f353658b9 Implement 'git checkout --patch'
This introduces a --patch mode for git-checkout.  In the index usage

  git checkout --patch -- [files...]

it lets the user discard edits from the <files> at the granularity of
hunks (by selecting hunks from 'git diff' and then reverse applying
them to the worktree).

We also accept a revision argument.  In the case

  git checkout --patch HEAD -- [files...]

we offer hunks from the difference between HEAD and the worktree, and
reverse applies them to both index and worktree, allowing you to
discard staged changes completely.  In the non-HEAD usage

  git checkout --patch <revision> -- [files...]

it offers hunks from the difference between the worktree and
<revision>.  The chosen hunks are then applied to both index and
worktree.

The application to worktree and index is done "atomically" in the
sense that we first check if the patch applies to the index (it should
always apply to the worktree).  If it does not, we give the user a
choice to either abort or apply to the worktree anyway.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-08-15 15:18:05 -07:00
Thomas Rast
d002ef4d94 Implement 'git reset --patch'
This introduces a --patch mode for git-reset.  The basic case is

  git reset --patch -- [files...]

which acts as the opposite of 'git add --patch -- [files...]': it
offers hunks for *un*staging.  Advanced usage is

  git reset --patch <revision> -- [files...]

which offers hunks from the diff between the index and <revision> for
forward application to the index.  (That is, the basic case is just
<revision> = HEAD.)

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-08-15 15:17:47 -07:00
Thomas Rast
3d792161b1 add -p: do not attempt to coalesce mode changes
In 0392513 (add-interactive: refactor mode hunk handling, 2009-04-16),
we merged the interaction loops for mode changes and hunk staging.
This was fine at the time, because 0beee4c (git-add--interactive:
remove hunk coalescing, 2008-07-02) removed hunk coalescing.

However, in 7a26e65 (Revert "git-add--interactive: remove hunk
coalescing", 2009-05-16), we resurrected it.  Since then, the code
would attempt in vain to merge mode changes with diff hunks,
corrupting both in the process.

We add a check to the coalescing loop to ensure it only looks at diff
hunks, thus skipping mode changes.

Noticed-by: Kirill Smelkov <kirr@mns.spb.ru>
Signed-off-by: Thomas Rast <trast@student.ethz.ch>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-08-15 10:36:59 -07:00
Thomas Rast
8f0bef6df9 git-apply--interactive: Refactor patch mode code
This makes some aspects of the 'git add -p' loop configurable (within
the code), so that we can later reuse git-add--interactive for other
similar tools.

Most fields are fairly straightforward, but APPLY gets a subroutine
(instead of just a string a la 'apply --cached') so that we can handle
'checkout -p', which will need to atomically apply the patch twice
(index and worktree).

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-08-14 12:40:09 -07:00
Thomas Rast
8dc3a47c3e add -i: do not dump patch during application
Remove a debugging print that snuck in at 7a26e65 (Revert
"git-add--interactive: remove hunk coalescing", 2009-05-16).

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-03 00:11:15 -07:00
Junio C Hamano
7a26e65392 Revert "git-add--interactive: remove hunk coalescing"
This reverts commit 0beee4c6de but with a
bit of twist, as we have added "edit hunk manually" hack and we cannot
rely on the original line numbers of the hunks that were manually edited.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-05-16 18:52:12 -07:00
Junio C Hamano
21590d5262 Merge branch 'mm/maint-add-p-quit'
* mm/maint-add-p-quit:
  git add -p: add missing "q" to patch prompt
2009-04-20 03:39:38 -07:00
Wincent Colaiuta
a2fc8d6536 git add -p: add missing "q" to patch prompt
Commit cbd3a01 added a new "q" subcommand to the "git add -p"
command loop, but forgot to add it to the prompt.

Signed-off-by: Wincent Colaiuta <win@wincent.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-20 03:38:44 -07:00
Jeff King
7535e5a16a add-interactive: refactor mode hunk handling
The original implementation considered the mode separately
from the rest of the hunks, asking about it outside the main
hunk-selection loop. This patch instead places a mode change
as the first hunk in the loop. This has two advantages:

  1. less duplicated code (since we use the main selection
     loop). This also cleans up an inconsistency, which is
     that the main selection loop separates options with a
     comma, whereas the mode prompt used slashes.

  2. users can now skip the mode change and come back to it,
     search for it (via "/mode"), etc, as they can with other
     hunks.

To facilitate this, each hunk is now marked with a "type".
Mode hunks are not considered for splitting (which would
make no sense, and also confuses the split_hunk function),
nor are they editable. In theory, one could edit the mode
lines and change to a new mode. In practice, there are only
two modes that git cares about (0644 and 0755), so either
you want to move from one to the other or not (and you can
do that by staging or not staging).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-19 12:35:38 -07:00
Matthieu Moy
cbd3a01ed8 git add -p: new "quit" command at the prompt.
There's already 'd' to stop staging hunks in a file, but no explicit
command to stop the interactive staging (for the current files and the
remaining ones).  Of course you can do 'd' and then ^C, but it would be
more intuitive to allow 'quit' action.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-19 12:35:37 -07:00