* [PATCH] git-gui: Unstaging a partly staged entry didn't update file_states correctly
From: Jens Lehmann @ 2009-12-07 20:35 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: Git Mailing List, Junio C Hamano
When unstaging a partly staged file or submodule, the file_states list
was not updated properly (unless unstaged linewise). Its index_info part
did not contain the former head_info as it should have but kept its old
value.
This seems not to have had any bad effects but diminishes the value of
the file_states list for future enhancements.
Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de>
---
I noticed this while whipping up another - soon to be released - patch
where the file_states list is used to access the hash values of staged
and unstaged changes.
AFAICS this buglet did not have negative effects until now because the
index_info hash value is not used.
git-gui/git-gui.sh | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh
index 037a1f2..9495789 100755
--- a/git-gui/git-gui.sh
+++ b/git-gui/git-gui.sh
@@ -1613,6 +1613,9 @@ proc merge_state {path new_state {head_info {}} {index_info {}}} {
} elseif {$s0 ne {_} && [string index $state 0] eq {_}
&& $head_info eq {}} {
set head_info $index_info
+ } elseif {$s0 eq {_} && [string index $state 0] ne {_}} {
+ set index_info $head_info
+ set head_info {}
}
set file_states($path) [list $s0$s1 $icon \
--
1.6.6.rc1.245.gcec33.dirty
^ permalink raw reply related
* Re: [RFC PATCH v3 7/8] Support remote archive from external protocol helpers
From: Ilari Liusvaara @ 2009-12-07 20:37 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: git
In-Reply-To: <20091207181227.GH17173@spearce.org>
On Mon, Dec 07, 2009 at 10:12:27AM -0800, Shawn O. Pearce wrote:
> Ilari Liusvaara <ilari.liusvaara@elisanet.fi> wrote:
> There is no such thing as invoke anymore.
Fixed.
-Ilari
^ permalink raw reply
* Re: [RFC/PATCHv10 01/11] fast-import: Proper notes tree manipulation
From: Junio C Hamano @ 2009-12-07 20:42 UTC (permalink / raw)
To: Johan Herland; +Cc: git, spearce
In-Reply-To: <1260185254-1523-2-git-send-email-johan@herland.net>
Johan Herland <johan@herland.net> writes:
> This patch teaches 'git fast-import' to automatically organize note objects
> in a fast-import stream into an appropriate fanout structure.
I really hate to sound like a clueless newbie, but that is what I am in
the area of 'notes', so I have two questions.
- What is the semantics of having more than one note to the same commit
in the input stream? Does the 'notes' part also have history and the
latest one overwrite the earlier one by creating a new commit that
points at the new 'notes' tree? I've always thought of 'notes' as an
unversioned metainfo, but I realize that versioning them would make
sense (you can and obviously would want to inspect the story behind the
current note attached to one particular commit).
- If however 'notes' want to have a history, how would it interact with
this rebalancing of the tree? Rebalancing makes a lot of sense if the
'notes' mechanism deals with the only one latest version because it can
keep the optimal look-up performance. There were some talks about
specialized merge strategies that can be made aware of rebalancing, but
is there a plan to deal with "git log -p notes" side, and how?
^ permalink raw reply
* Re: [RFC/PATCHv10 08/11] Notes API: get_note(): Return the note annotating the given object
From: Junio C Hamano @ 2009-12-07 20:52 UTC (permalink / raw)
To: Johan Herland; +Cc: git, spearce
In-Reply-To: <1260185254-1523-9-git-send-email-johan@herland.net>
Johan Herland <johan@herland.net> writes:
> Created by a simple cleanup and rename of lookup_notes().
>
> Signed-off-by: Johan Herland <johan@herland.net>
> ---
> notes.c | 15 ++++++++-------
> notes.h | 3 +++
> 2 files changed, 11 insertions(+), 7 deletions(-)
>
> diff --git a/notes.c b/notes.c
> index 79bfa24..110404a 100644
> --- a/notes.c
> +++ b/notes.c
> @@ -379,12 +379,13 @@ void add_note(const unsigned char *object_sha1, const unsigned char *note_sha1)
> note_tree_insert(&root_node, 0, l, PTR_TYPE_NOTE);
> }
>
> -static unsigned char *lookup_notes(const unsigned char *object_sha1)
> +const unsigned char *get_note(const unsigned char *object_sha1)
Is there a need to find "note for this commit in the set of notes 3 days
ago"? IOW, reading note for the given commit not from the tip of the
history of the refs/notes/commits but from say refs/notes/commits~4?
Similarly, is there a need to ask for a history of notes for a given
commit, something like "git log refs/notes/commit/$this_commit" in a world
without any fanout?
Obviously, "there is no need because..." is the best answer I'd be happy
with. "There may be in the future but we haven't identified a good use
case and we don't implement what we do not need now." is also perfectly
acceptable.
IOW, I am not suggesting to change it---I just want to know how much
thought went in before deciding to implement the interface this way.
^ permalink raw reply
* Re: [BUG] git config does not reuse section name
From: Junio C Hamano @ 2009-12-07 20:54 UTC (permalink / raw)
To: Sverre Rabbelier; +Cc: Junio C Hamano, Yakup Akbay, git, Johannes Schindelin
In-Reply-To: <fabb9a1e0912071223l21c70e2ax9b0e3c9976ae9d7@mail.gmail.com>
Sverre Rabbelier <srabbelier@gmail.com> writes:
> On Mon, Dec 7, 2009 at 21:04, Junio C Hamano <gitster@pobox.com> wrote:
>> If I recall correctly, this hasn't been even noticed/reported/recognized
>> as an issue, ever since the "git repo-config" was introduced (which later
>> was renamed to "git config").
>
> I poked Dscho about it at some point.
>
>> Dscho, do you remember details?
>
> He told me that the 'git config' code is so horrible that it's
> nigh-impossible to change the behavior, hence why he didn't do it :P.
Hmm, sad. I thought it was mostly his code...
^ permalink raw reply
* Re: [PATCH 2/2] git-rm doc: Describe how to sync index & work tree
From: Junio C Hamano @ 2009-12-07 21:08 UTC (permalink / raw)
To: Björn Gustavsson; +Cc: git
In-Reply-To: <4B1D4AFE.6090708@gmail.com>
Looks sensible.
I think mentioning "add -u" in the same section as "commit -a" would be
helpful, as these two are more for user's own development (as opposed to
vendor-code-drop). I'd perhaps squash something like this in. Please say
"yes", "don't, it is horrible", or something in between ;-)
--
Documentation/git-rm.txt | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/Documentation/git-rm.txt b/Documentation/git-rm.txt
index c622972..42161d7 100644
--- a/Documentation/git-rm.txt
+++ b/Documentation/git-rm.txt
@@ -94,7 +94,8 @@ If you intend that your next commit should record all modifications
of tracked files in the working tree and record all removals of
files that have been removed from the working tree with `rm`
(as opposed to `git rm`), use `git commit -a`, as it will
-automatically notice and record all removals.
+automatically notice and record all removals. `git add -u`
+can be used for a similar effect without commiting.
Using "git add -A"
~~~~~~~~~~~~~~~~~~
^ permalink raw reply related
* Re: How do you best store structured data in git repositories?
From: Sebastian Setzer @ 2009-12-07 21:20 UTC (permalink / raw)
To: git
In-Reply-To: <20091204001359.GA6709@gmail.com>
On Thursday, Dec 03 2009 at 16:14 -0800, David Aguilar wrote:
> On Wed, Dec 02, 2009 at 04:17:10PM -0500, Avery Pennarun wrote:
> > On Wed, Dec 2, 2009 at 4:08 PM, Sebastian Setzer
> > <sebastianspublicaddress@googlemail.com> wrote:
> > > Do you use XML for this purpose?
> >
> > XML is terrible for most data storage purposes.
>
> I agree 100%.
>
> JSON's not too bad for data structures and is known to
> be friendly to XML expats.
>
Sorry, I didn't want to start a flamewar against XML. I'm no big friend
of XML myself, but I don't know of an (open source) diff-/merge tool for
any general purpose file format other than XML or plain text.
When you mention other formats, I'd be interested in
- why this format is good for storage in git
- if there are merge tools available which ensure that, after a merge,
the structure (and maybe additional contraints) is still valid.
Thanks for your comments,
Sebastian
^ permalink raw reply
* Re: [RFC PATCH v3 5/8] Support taking over transports
From: Ilari Liusvaara @ 2009-12-07 21:19 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: git
In-Reply-To: <20091207174947.GF17173@spearce.org>
On Mon, Dec 07, 2009 at 09:49:47AM -0800, Shawn O. Pearce wrote:
>
> > + if (duped < 0)
> > + die_errno("Can't dup helper output fd");
> > + data->out = xfdopen(duped, "r");
> > + setvbuf(data->out, NULL, _IONBF, 0);
>
> I wonder if this is really a good idea. Most helpers actually
> use a lot of text based IO to communicate. Disabling buffering
> for those helpers to avoid overreading the advertisement from a
> connect is a problem.
I dropped the buffering change.
> Maybe we could leave buffering on, but use a handshake protocol
> with the helper during connect:
>
> (1) > "connect git-upload-pack\n"
> (2) < "\n"
> (3) > "begin\n"
>
> During 2 we are still buffered, but the only content on the pipe
> should be the single blank line, so we pull that in and the FILE*
> buffer should be empty.
Doesn't work. Stream buffering can only be changed before first
I/O.
I figured out a solution. Dup the file descriptor second time and
make another FILE* for it. Then send the connect and read the
response over the new stream. This avoids overreading and allows
other I/O to be buffered. After connect attempt, the new streaam
can be closed.
This way most of the I/O can be buffered, only reading responses
to connect commands can't, and that is at most 1 byte if fallbacks
aren't required. And the thing fits nicely inside _process_connect().
Oh, and no protocol change needed.
-Ilari
^ permalink raw reply
* Re: git-apply fails on creating a new file, with both -p and --directory specified
From: James Vega @ 2009-12-07 21:35 UTC (permalink / raw)
To: git
In-Reply-To: <7vws1e3ma1.fsf@alter.siamese.dyndns.org>
Junio C Hamano <gitster <at> pobox.com> writes:
>
> "Steven J. Murdoch" <git+Steven.Murdoch <at> cl.cam.ac.uk> writes:
>
> > This appears to be because I was both using -p to strip some path
> > components, and --directory to add different ones in. Only creating
> > new files was affected.
>
> A very nicely done report.
>
> In addition to your test case, I suspect that a patch that only changes
> mode would have acted funny with -p<n> option.
>
It looks like this may have introduced a bug when staging a file
removal. Here's an example git session showing the issue:
$ git init test
Initialized empty Git repository in /local_disk/tmp/test/.git/
$ cd test
$ echo "foo" > foo
$ git add foo
$ git commit -m 'Add foo'
[master (root-commit) 3643b5d] Add foo
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 foo
$ mv foo bar
$ git add -p
diff --git a/foo b/foo
index 257cc56..0000000
--- a/foo
+++ /dev/null
@@ -1 +0,0 @@
-foo
Stage this hunk [y,n,q,a,d,/,e,?]? y
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD ..." to unstage)
#
# new file: dev/null
# deleted: foo
#
# Changed but not updated:
# (use "git add/rm ..." to update what will be committed)
# (use "git checkout -- ..." to discard changes in working directory)
#
# deleted: dev/null
#
# Untracked files:
# (use "git add ..." to include in what will be committed)
#
# bar
Replacing the 'git add -p' with
git diff | sed '/^deleted file/d' | git apply --cached
also exhibits the problem.
^ permalink raw reply related
* Re: [RFC PATCH v3 0/8] Remote helpers smart transport extensions
From: Nanako Shiraishi @ 2009-12-07 22:25 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Erik Faye-Lund, Nicolas Pitre, Ilari Liusvaara, git
In-Reply-To: <7vein635vn.fsf@alter.siamese.dyndns.org>
Quoting Junio C Hamano <gitster@pobox.com>
> Nanako Shiraishi <nanako3@lavabit.com> writes:
>
>> Quoting Junio C Hamano <gitster@pobox.com>
>>
>>> I queued to ease the discussion in 'pu'. I had to fix-up some conflicts
>>> while doing so. Please sanity check the result.
>>
>> I see that you changed many "char* variable" to "char *variable", but
>> what is the reason for these changes?
>
> Nico already gave you correct and more concise version; this more verbose
> explanation is primarily for you who said a few times that you are not
> fluent in C. Others can skip this message without missing anything.
Thanks everybody for quick answers and thank you, Junio,
for a detailed explanation. Now I understand.
--
Nanako Shiraishi
http://ivory.ap.teacup.com/nanako3/
^ permalink raw reply
* Re: [PATCH] Add commit.infodisplay option to give message editor empty file
From: James P. Howard, II @ 2009-12-07 22:43 UTC (permalink / raw)
To: Jeff King; +Cc: git
In-Reply-To: <20091206042206.GC23983@coredump.intra.peff.net>
On Sat, Dec 5, 2009 at 23:22, Jeff King <peff@peff.net> wrote:
> Probably "--no-status" would be a good name, as the generated template
> is the format generated by "git status".
I have produced a patch against master that implements this in, what I
hope, is a better way.
James
--
James P. Howard, II, MPA MBCS
jh@jameshoward.us
^ permalink raw reply
* [PATCH] Add commit.status, --status, and --no-status
From: James P. Howard, II @ 2009-12-07 22:45 UTC (permalink / raw)
To: git; +Cc: James P. Howard, II
In-Reply-To: <20091206131217.GA12851@sigill.intra.peff.net>
This commit provides support for commit.status, --status, and
--no-status, which control whether or not the git status information
is included in the commit message template when using an editor to
prepare the commit message. It does not affect the effects of a
user's commit.template settings.
Signed-off-by: James P. Howard, II <jh@jameshoward.us>
---
Documentation/config.txt | 5 +++++
Documentation/git-commit.txt | 14 +++++++++++++-
builtin-commit.c | 9 +++++++--
3 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index a1e36d7..5561560 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -705,6 +705,11 @@ color.ui::
terminal. When more specific variables of color.* are set, they always
take precedence over this setting. Defaults to false.
+commit.status
+ A boolean to enable/disable inclusion of status information in the
+ commit message template when using an editor to prepare the commit
+ message. Defaults to true.
+
commit.template::
Specify a file to use as the template for new commit messages.
"{tilde}/" is expanded to the value of `$HOME` and "{tilde}user/" to the
diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt
index d227cec..0e53518 100644
--- a/Documentation/git-commit.txt
+++ b/Documentation/git-commit.txt
@@ -11,7 +11,8 @@ SYNOPSIS
'git commit' [-a | --interactive] [-s] [-v] [-u<mode>] [--amend] [--dry-run]
[(-c | -C) <commit>] [-F <file> | -m <msg>] [--reset-author]
[--allow-empty] [--no-verify] [-e] [--author=<author>]
- [--cleanup=<mode>] [--] [[-i | -o ]<file>...]
+ [--cleanup=<mode>] [--status | --no-status] [--]
+ [[-i | -o ]<file>...]
DESCRIPTION
-----------
@@ -207,6 +208,17 @@ specified.
to be committed, paths with local changes that will be left
uncommitted and paths that are untracked.
+--status::
+ Include the output of linkgit:git-status[1] in the commit
+ message template when using an editor to prepare the commit
+ message. Defaults to on, but can be used to override
+ configuration variable commit.status.
+
+--no-status::
+ Do not include the output of linkgit:git-status[1] in the
+ commit message template when using an editor to prepare the
+ default commit message.
+
\--::
Do not interpret any more arguments as options.
diff --git a/builtin-commit.c b/builtin-commit.c
index e93a647..095c186 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -67,7 +67,7 @@ static enum {
} cleanup_mode;
static char *cleanup_arg;
-static int use_editor = 1, initial_commit, in_merge;
+static int use_editor = 1, initial_commit, in_merge, include_status = 1;
static const char *only_include_assumed;
static struct strbuf message;
@@ -97,6 +97,7 @@ static struct option builtin_commit_options[] = {
OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
OPT_FILENAME('t', "template", &template_file, "use specified template file"),
OPT_BOOLEAN('e', "edit", &edit_flag, "force edit of commit"),
+ OPT_BOOLEAN(0, "status", &include_status, "include status in commit message template"),
OPT_GROUP("Commit contents options"),
OPT_BOOLEAN('a', "all", &all, "commit all changed files"),
@@ -547,7 +548,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
/* This checks if committer ident is explicitly given */
git_committer_info(0);
- if (use_editor) {
+ if (use_editor && include_status) {
char *author_ident;
const char *committer_ident;
@@ -1006,6 +1007,10 @@ static int git_commit_config(const char *k, const char *v, void *cb)
if (!strcmp(k, "commit.template"))
return git_config_pathname(&template_file, k, v);
+ if (!strcmp(k, "commit.status")) {
+ include_status = git_config_bool(k, v);
+ return 0;
+ }
return git_status_config(k, v, s);
}
--
1.6.5.3
^ permalink raw reply related
* Re: Re: [RFC PATCH v2 0/2] git-gui: (un)stage a range of changes at once
From: Jeff Epler @ 2009-12-08 0:38 UTC (permalink / raw)
To: Heiko Voigt; +Cc: Shawn O. Pearce, git
In-Reply-To: <20091207125435.GA43609@book.hvoigt.net>
On Mon, Dec 07, 2009 at 01:54:35PM +0100, Heiko Voigt wrote:
> Jeff could you clarify or provide an example?
If I recall correctly, the problem with the v2 patch was when the change
was like
@@ -13,8 +13,8 @@ set appvers {@@GITGUI_VERSION@@}
set copyright [encoding convertfrom utf-8 {
Copyright © 2006, 2007 Shawn Pearce, et. al.
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
+blah blah
+blah blah
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
and the 'blah blah' lines were both staged in the same operation.
When doing this, the staged change is actually
+blah blah
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+blah blah
but the change that should have been staged is:
+blah blah
+blah blah
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Since it requires staging multiple "+" lines in one go, this problem
doesn't exist in git-gui before my changes.
The v3 patch I posted just a few minutes ago fixes this problem.
Jeff
^ permalink raw reply
* Re: [PATCH] Add commit.status, --status, and --no-status
From: James Pickens @ 2009-12-08 0:39 UTC (permalink / raw)
To: James P. Howard, II; +Cc: git
In-Reply-To: <1260225927-33612-1-git-send-email-jh@jameshoward.us>
On Mon, Dec 7, 2009, James P. Howard, II <jh@jameshoward.us> wrote:
> This commit provides support for commit.status, --status, and
> --no-status, which control whether or not the git status information
> is included in the commit message template when using an editor to
> prepare the commit message. It does not affect the effects of a
> user's commit.template settings.
At the risk of sounding like a curmudgeon, I have to register an objection
to this _as a config option_, for the same reasons that I objected to the
'grep --full-tree' config option [1]. Both options fundamentally change
user visible behavior, both options IMHO will be used by a small minority
of git users, and in both cases, the desired behavior can be attained using
aliases in combination with a new command line option.
Sorry if I'm obstructing progress, but I think that, for the good of the
Git community as a whole, it's best to keep the number of config options
(and to a lesser extent, command line options) as low as possible.
Note that I do not object to adding --no-status as a command line option.
[1] http://article.gmane.org/gmane.comp.version-control.git/133681
James
^ permalink raw reply
* [PATCHv3 0/2] git-gui: (un)stage a range of changes at once
From: jepler @ 2009-12-08 0:22 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: git, Heiko Voigt, Peter Baumann, Jeff Epler
From: Jeff Epler <jepler@unpythonic.net>
This set of patches allows git-gui to stage multiple lines at once by
selecting the range and then using the "apply lines" item in the context
menu.
Compared to the earlier versions, I've fixed all the bugs I became aware of.
I've also added the missing signed-off-by.
The first patch fixes an existing bug in git-gui when staging a deletion
followed by another deletion followed by the end of the file.
Jeff Epler (2):
Fix applying a line when all following lines are deletions
Make it possible to apply a range of changes at once
git-gui.sh | 15 +++-
lib/diff.tcl | 241 ++++++++++++++++++++++++++++++++++------------------------
2 files changed, 153 insertions(+), 103 deletions(-)
^ permalink raw reply
* [PATCH 1/2] Fix applying a line when all following lines are deletions
From: jepler @ 2009-12-08 0:22 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: git, Heiko Voigt, Peter Baumann, Jeff Epler
In-Reply-To: <1260231763-19194-1-git-send-email-jepler@unpythonic.net>
From: Jeff Epler <jepler@unpythonic.net>
If a diff looked like
@@
context
-del1
-del2
and you wanted to stage the deletion 'del1', the generated patch wouldn't
apply because it was missing the line 'del2' converted to context, but
this line was counted in the @@-line
Signed-off-by: Jeff Epler <jepler@unpythonic.net>
---
lib/diff.tcl | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/lib/diff.tcl b/lib/diff.tcl
index bd5d189..066755b 100644
--- a/lib/diff.tcl
+++ b/lib/diff.tcl
@@ -664,6 +664,7 @@ proc apply_line {x y} {
}
set i_l $next_l
}
+ set patch "$patch$pre_context"
set patch "@@ -$hln,$n +$hln,[eval expr $n $sign 1] @@\n$patch"
if {[catch {
--
1.6.3.3
^ permalink raw reply related
* [PATCH 2/2] Make it possible to apply a range of changes at once
From: jepler @ 2009-12-08 0:22 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: git, Heiko Voigt, Peter Baumann, Jeff Epler
In-Reply-To: <1260231763-19194-1-git-send-email-jepler@unpythonic.net>
From: Jeff Epler <jepler@unpythonic.net>
Signed-off-by: Jeff Epler <jepler@unpythonic.net>
---
git-gui.sh | 15 +++-
lib/diff.tcl | 242 ++++++++++++++++++++++++++++++++++------------------------
2 files changed, 153 insertions(+), 104 deletions(-)
diff --git a/git-gui.sh b/git-gui.sh
index 718277a..803423f 100755
--- a/git-gui.sh
+++ b/git-gui.sh
@@ -3199,7 +3199,7 @@ set ui_diff_applyhunk [$ctxm index last]
lappend diff_actions [list $ctxm entryconf $ui_diff_applyhunk -state]
$ctxm add command \
-label [mc "Apply/Reverse Line"] \
- -command {apply_line $cursorX $cursorY; do_rescan}
+ -command {apply_range_or_line $cursorX $cursorY; do_rescan}
set ui_diff_applyline [$ctxm index last]
lappend diff_actions [list $ctxm entryconf $ui_diff_applyline -state]
$ctxm add separator
@@ -3239,12 +3239,21 @@ proc popup_diff_menu {ctxm ctxmmg x y X Y} {
if {[string first {U} $state] >= 0} {
tk_popup $ctxmmg $X $Y
} else {
+ set has_range [expr {[$::ui_diff tag nextrange sel 0.0] != {}}]
if {$::ui_index eq $::current_diff_side} {
set l [mc "Unstage Hunk From Commit"]
- set t [mc "Unstage Line From Commit"]
+ if {$has_range} {
+ set t [mc "Unstage Lines From Commit"]
+ } else {
+ set t [mc "Unstage Line From Commit"]
+ }
} else {
set l [mc "Stage Hunk For Commit"]
- set t [mc "Stage Line For Commit"]
+ if {$has_range} {
+ set t [mc "Stage Lines For Commit"]
+ } else {
+ set t [mc "Stage Line For Commit"]
+ }
}
if {$::is_3way_diff || $::is_submodule_diff
|| $current_diff_path eq {}
diff --git a/lib/diff.tcl b/lib/diff.tcl
index 066755b..5e738e2 100644
--- a/lib/diff.tcl
+++ b/lib/diff.tcl
@@ -533,10 +533,23 @@ proc apply_hunk {x y} {
}
}
-proc apply_line {x y} {
+proc apply_range_or_line {x y} {
global current_diff_path current_diff_header current_diff_side
global ui_diff ui_index file_states
+ set selected [$ui_diff tag nextrange sel 0.0]
+
+ if {$selected == {}} {
+ set first [$ui_diff index "@$x,$y"]
+ set last $first
+ } else {
+ set first [lindex $selected 0]
+ set last [lindex $selected 1]
+ }
+
+ set first_l [$ui_diff index "$first linestart"]
+ set last_l [$ui_diff index "$last lineend"]
+
if {$current_diff_path eq {} || $current_diff_header eq {}} return
if {![lock_index apply_hunk]} return
@@ -559,120 +572,147 @@ proc apply_line {x y} {
}
}
- set the_l [$ui_diff index @$x,$y]
+ set wholepatch {}
- # operate only on change lines
- set c1 [$ui_diff get "$the_l linestart"]
- if {$c1 ne {+} && $c1 ne {-}} {
- unlock_index
- return
- }
- set sign $c1
-
- set i_l [$ui_diff search -backwards -regexp ^@@ $the_l 0.0]
- if {$i_l eq {}} {
- unlock_index
- return
- }
- # $i_l is now at the beginning of a line
+ while {$first_l < $last_l} {
+ set i_l [$ui_diff search -backwards -regexp ^@@ $first_l 0.0]
+ if {$i_l eq {}} {
+ # If there's not a @@ above, then the selected range
+ # must have come before the first_l @@
+ set i_l [$ui_diff search -regexp ^@@ $first_l $last_l]
+ }
+ if {$i_l eq {}} {
+ unlock_index
+ return
+ }
+ # $i_l is now at the beginning of a line
- # pick start line number from hunk header
- set hh [$ui_diff get $i_l "$i_l + 1 lines"]
- set hh [lindex [split $hh ,] 0]
- set hln [lindex [split $hh -] 1]
+ # pick start line number from hunk header
+ set hh [$ui_diff get $i_l "$i_l + 1 lines"]
+ set hh [lindex [split $hh ,] 0]
+ set hln [lindex [split $hh -] 1]
- # There is a special situation to take care of. Consider this hunk:
- #
- # @@ -10,4 +10,4 @@
- # context before
- # -old 1
- # -old 2
- # +new 1
- # +new 2
- # context after
- #
- # We used to keep the context lines in the order they appear in the
- # hunk. But then it is not possible to correctly stage only
- # "-old 1" and "+new 1" - it would result in this staged text:
- #
- # context before
- # old 2
- # new 1
- # context after
- #
- # (By symmetry it is not possible to *un*stage "old 2" and "new 2".)
- #
- # We resolve the problem by introducing an asymmetry, namely, when
- # a "+" line is *staged*, it is moved in front of the context lines
- # that are generated from the "-" lines that are immediately before
- # the "+" block. That is, we construct this patch:
- #
- # @@ -10,4 +10,5 @@
- # context before
- # +new 1
- # old 1
- # old 2
- # context after
- #
- # But we do *not* treat "-" lines that are *un*staged in a special
- # way.
- #
- # With this asymmetry it is possible to stage the change
- # "old 1" -> "new 1" directly, and to stage the change
- # "old 2" -> "new 2" by first staging the entire hunk and
- # then unstaging the change "old 1" -> "new 1".
-
- # This is non-empty if and only if we are _staging_ changes;
- # then it accumulates the consecutive "-" lines (after converting
- # them to context lines) in order to be moved after the "+" change
- # line.
- set pre_context {}
-
- set n 0
- set i_l [$ui_diff index "$i_l + 1 lines"]
- set patch {}
- while {[$ui_diff compare $i_l < "end - 1 chars"] &&
- [$ui_diff get $i_l "$i_l + 2 chars"] ne {@@}} {
- set next_l [$ui_diff index "$i_l + 1 lines"]
- set c1 [$ui_diff get $i_l]
- if {[$ui_diff compare $i_l <= $the_l] &&
- [$ui_diff compare $the_l < $next_l]} {
- # the line to stage/unstage
- set ln [$ui_diff get $i_l $next_l]
- if {$c1 eq {-}} {
- set n [expr $n+1]
+ # There is a special situation to take care of. Consider this
+ # hunk:
+ #
+ # @@ -10,4 +10,4 @@
+ # context before
+ # -old 1
+ # -old 2
+ # +new 1
+ # +new 2
+ # context after
+ #
+ # We used to keep the context lines in the order they appear in
+ # the hunk. But then it is not possible to correctly stage only
+ # "-old 1" and "+new 1" - it would result in this staged text:
+ #
+ # context before
+ # old 2
+ # new 1
+ # context after
+ #
+ # (By symmetry it is not possible to *un*stage "old 2" and "new
+ # 2".)
+ #
+ # We resolve the problem by introducing an asymmetry, namely,
+ # when a "+" line is *staged*, it is moved in front of the
+ # context lines that are generated from the "-" lines that are
+ # immediately before the "+" block. That is, we construct this
+ # patch:
+ #
+ # @@ -10,4 +10,5 @@
+ # context before
+ # +new 1
+ # old 1
+ # old 2
+ # context after
+ #
+ # But we do *not* treat "-" lines that are *un*staged in a
+ # special way.
+ #
+ # With this asymmetry it is possible to stage the change "old
+ # 1" -> "new 1" directly, and to stage the change "old 2" ->
+ # "new 2" by first staging the entire hunk and then unstaging
+ # the change "old 1" -> "new 1".
+ #
+ # Applying multiple lines adds complexity to the special
+ # situation. The pre_context must be moved after the entire
+ # first block of consecutive staged "+" lines, so that
+ # staging both additions gives the following patch:
+ #
+ # @@ -10,4 +10,6 @@
+ # context before
+ # +new 1
+ # +new 2
+ # old 1
+ # old 2
+ # context after
+
+ # This is non-empty if and only if we are _staging_ changes;
+ # then it accumulates the consecutive "-" lines (after
+ # converting them to context lines) in order to be moved after
+ # "+" change lines.
+ set pre_context {}
+
+ set n 0
+ set m 0
+ set i_l [$ui_diff index "$i_l + 1 lines"]
+ set patch {}
+ while {[$ui_diff compare $i_l < "end - 1 chars"] &&
+ [$ui_diff get $i_l "$i_l + 2 chars"] ne {@@}} {
+ set next_l [$ui_diff index "$i_l + 1 lines"]
+ set c1 [$ui_diff get $i_l]
+ if {[$ui_diff compare $first_l <= $i_l] &&
+ [$ui_diff compare $i_l < $last_l] &&
+ ($c1 eq {-} || $c1 eq {+})} {
+ # a line to stage/unstage
+ set ln [$ui_diff get $i_l $next_l]
+ if {$c1 eq {-}} {
+ set n [expr $n+1]
+ set patch "$patch$pre_context$ln"
+ set pre_context {}
+ } else {
+ set m [expr $m+1]
+ set patch "$patch$ln"
+ }
+ } elseif {$c1 ne {-} && $c1 ne {+}} {
+ # context line
+ set ln [$ui_diff get $i_l $next_l]
set patch "$patch$pre_context$ln"
+ set n [expr $n+1]
+ set m [expr $m+1]
+ set pre_context {}
+ } elseif {$c1 eq $to_context} {
+ # turn change line into context line
+ set ln [$ui_diff get "$i_l + 1 chars" $next_l]
+ if {$c1 eq {-}} {
+ set pre_context "$pre_context $ln"
+ } else {
+ set patch "$patch $ln"
+ }
+ set n [expr $n+1]
+ set m [expr $m+1]
} else {
- set patch "$patch$ln$pre_context"
- }
- set pre_context {}
- } elseif {$c1 ne {-} && $c1 ne {+}} {
- # context line
- set ln [$ui_diff get $i_l $next_l]
- set patch "$patch$pre_context$ln"
- set n [expr $n+1]
- set pre_context {}
- } elseif {$c1 eq $to_context} {
- # turn change line into context line
- set ln [$ui_diff get "$i_l + 1 chars" $next_l]
- if {$c1 eq {-}} {
- set pre_context "$pre_context $ln"
- } else {
- set patch "$patch $ln"
+ # a change in the opposite direction of
+ # to_context which is outside the range of
+ # lines to apply.
+ set patch "$patch$pre_context"
+ set pre_context {}
}
- set n [expr $n+1]
+ set i_l $next_l
}
- set i_l $next_l
+ set patch "$patch$pre_context"
+ set wholepatch "$wholepatch@@ -$hln,$n +$hln,$m @@\n$patch"
+ set first_l [$ui_diff index "$next_l + 1 lines"]
}
- set patch "$patch$pre_context"
- set patch "@@ -$hln,$n +$hln,[eval expr $n $sign 1] @@\n$patch"
if {[catch {
set enc [get_path_encoding $current_diff_path]
set p [eval git_write $apply_cmd]
fconfigure $p -translation binary -encoding $enc
puts -nonewline $p $current_diff_header
- puts -nonewline $p $patch
+ puts -nonewline $p $wholepatch
close $p} err]} {
error_popup [append $failed_msg "\n\n$err"]
}
--
1.6.3.3
^ permalink raw reply related
* Generic filters for git archive?
From: Russ Dill @ 2009-12-08 1:06 UTC (permalink / raw)
To: git
I'm trying to add copyright headers to my source files as they are
exported via git archive. eg:
* $Copyright$
to
* Copyright (c) 2003-2009 by Foo Bar
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
And properly handling things like '# $Copyright$', '// $Copyright$',
etc. I have a sed script that does this, but no way to apply it to the
output of git archive. I tried setting up a smudge filter that would
only smudge output on archive exports, but it doesn't appear that the
smudge filters get run on git archive.
I am currently running 1.6.3.3
^ permalink raw reply
* Re: [RFC/PATCHv10 01/11] fast-import: Proper notes tree manipulation
From: Johan Herland @ 2009-12-08 1:44 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: git, gitster
In-Reply-To: <20091207164130.GD17173@spearce.org>
On Monday 07 December 2009, Shawn O. Pearce wrote:
> Johan Herland <johan@herland.net> wrote:
> > +static uintmax_t do_change_note_fanout(
> > + struct tree_entry *orig_root, struct tree_entry *root,
> > + char *hex_sha1, unsigned int hex_sha1_len,
> > + char *fullpath, unsigned int fullpath_len,
> > + unsigned char fanout)
>
> I think this function winds up processing all notes twice. Yuck.
>
> tree_content_set() adds a new tree entry to the end of the current
> tree. So when converting "1a9029b006484e8b9aca06ff261beb2324bb9916"
> into "1a" (to go from fanout 0 to fanout 1) we'll place 1a at the
> end of orig_root, and this function will walk 1a/ recursively,
> examining 1a9029b006484e8b9aca06ff261beb2324bb9916 all over again.
Yep, you're right. Still, we only do the tree_content_remove()/set() once
per note, so although performance is probably not abysmal, we are still
clearly suboptimal.
Also, keep in mind that change_note_fanout() is only called when the number
of notes crosses a power of 256. Thus for typical notes trees (which are
assumed to mostly accumulate notes over their lifetime),
change_note_fanout() will be called zero, one or two times (depending on the
final number of notes).
> If we're here, isn't it likely that *all* notes are in the wrong
> path in the tree, and we need to move them all to a new location?
> If that's true then should we instead just build an entirely new
> tree and swap the root when we are done?
Hmm. Not always. In your earlier scenario where we add 2,000,000 notes in a
single commit, the current code would need to rewrite 255 of them from
fanout 0 to fanout 2, and 65,535 of them from fanout 1 to fanout 2. But the
vast majority (1,934,465) would not require rewriting (having been added at
the correct fanout initially). However, if we build a new tree (by which I
assume you mean tree_content_remove() from the old tree and
tree_content_set() to the new tree for every single note (and non-note)), we
end up processing all 2,000,000 entries.
> As we empty out a tree the object will be recycled into a pool of
> trees which can be reused at a later point. It might actually make
> sense to build the new tree under a different root. We won't scan
> entries we've moved, and the memory difference should be fairly
> small as tree_content_remove() will make a subtree available for
> reuse as soon as its empty. So we're only dealing with a handful
> of additional tree objects as we do the conversion.
I'm not sure I get the details here. How can we avoid doing the
_remove()/_set() from/to the old/new tree for every tree_entry? In other
words, how do we avoid removing and re-setting the 2,000,000 notes in the
above example?
Thanks for the review!
...Johan
--
Johan Herland, <johan@herland.net>
www.herland.net
^ permalink raw reply
* Re: [RFC/PATCHv10 01/11] fast-import: Proper notes tree manipulation
From: Johan Herland @ 2009-12-08 1:55 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: git, gitster
In-Reply-To: <20091207164311.GE17173@spearce.org>
On Monday 07 December 2009, Shawn O. Pearce wrote:
> Johan Herland <johan@herland.net> wrote:
> > +static unsigned char convert_num_notes_to_fanout(uintmax_t num_notes)
> > +{
> > + unsigned char fanout = 0;
> > + while ((num_notes >>= 8))
> > + fanout++;
> > + return fanout;
> > +}
> > +
> > +static void construct_path_with_fanout(const char *hex_sha1,
> > + unsigned char fanout, char *path)
> > +{
> > + unsigned int i = 0, j = 0;
> > + if (fanout >= 20)
> > + die("Too large fanout (%u)", fanout);
>
> Shouldn't convert_num_notes_to_fanout have a guard to prevent this
> case from happening?
Well, it sort of already does (unless uintmax_t is more than 19 * 8 = 152
bits wide... ;)
Not sure what you're getting at:
- Should I add a "&& fanout < 19" condition to the while loop in
convert_num_notes_to_fanout()?
- Should I remove the "if (fanout >= 20) die(...)"? Of course,
construct_path_with_fanout() is only supposed to be called with values
returned from convert_num_notes_to_fanout(), so the condition only tests a
precondition that we believe to be true (FTR, it was converted from an
equivalent assert() in an earlier iteration), but I normally test for these
things anyway (when they are not blindingly obvious), just to make sure...
(and I believe a die(...) is kinder to the user than a segfault...)
...Johan
--
Johan Herland, <johan@herland.net>
www.herland.net
^ permalink raw reply
* Re: [BUG] git config does not reuse section name
From: Johannes Schindelin @ 2009-12-08 2:01 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Yakup Akbay, git
In-Reply-To: <7vy6le35zv.fsf@alter.siamese.dyndns.org>
Hi,
On Mon, 7 Dec 2009, Junio C Hamano wrote:
> Yakup Akbay <yakbay@ubicom.com> writes:
>
> > When I repeat the following n times
> >
> > $ git config color.ui always
> > $ git config --unset color.ui
> >
> >
> > it ends up the section name [color] n times in the .git/config file.
> >
> >
> >
> > like this for n=4:
> >
> > [color]
> > [color]
> > [color]
> > [color]
> >
> >
> > Using git version 1.6.5.3 (I don't know whether this is already fixed
> > in in later versions)
>
> If I recall correctly, this hasn't been even noticed/reported/recognized
> as an issue, ever since the "git repo-config" was introduced (which later
> was renamed to "git config"). Dscho, do you remember details?
IIRC, due to technical limitations, the config machinery only recognizes
sections if there is at least _one_ entry in them. This is because
git_config() is used to determine (from the current file position) where
the section begins.
And likewise, due to those technical limitations, the section header is
not removed when the last entry in the section is removed (this was
because I did not want to change the location of the section, but due to
the mentioned limitation, that did not work out).
Ciao,
Dscho
^ permalink raw reply
* Re: [RFC/PATCHv10 01/11] fast-import: Proper notes tree manipulation
From: Shawn O. Pearce @ 2009-12-08 1:59 UTC (permalink / raw)
To: Johan Herland; +Cc: git, gitster
In-Reply-To: <200912080255.17568.johan@herland.net>
Johan Herland <johan@herland.net> wrote:
> On Monday 07 December 2009, Shawn O. Pearce wrote:
> > > + if (fanout >= 20)
> > > + die("Too large fanout (%u)", fanout);
> >
> > Shouldn't convert_num_notes_to_fanout have a guard to prevent this
> > case from happening?
>
> Well, it sort of already does (unless uintmax_t is more than 19 * 8 = 152
> bits wide... ;)
Oh, good point. :-)
> Not sure what you're getting at:
>
> - Should I add a "&& fanout < 19" condition to the while loop in
> convert_num_notes_to_fanout()?
That's what I was thinking. But given the 19 * 8 = 152 case above,
this is pointless.
--
Shawn.
^ permalink raw reply
* Re: [BUG] git config does not reuse section name
From: Johannes Schindelin @ 2009-12-08 2:05 UTC (permalink / raw)
To: Sverre Rabbelier; +Cc: Junio C Hamano, Yakup Akbay, git
In-Reply-To: <fabb9a1e0912071223l21c70e2ax9b0e3c9976ae9d7@mail.gmail.com>
Hi,
On Mon, 7 Dec 2009, Sverre Rabbelier wrote:
> On Mon, Dec 7, 2009 at 21:04, Junio C Hamano <gitster@pobox.com> wrote:
> > If I recall correctly, this hasn't been even
> > noticed/reported/recognized as an issue, ever since the "git
> > repo-config" was introduced (which later was renamed to "git config").
>
> I poked Dscho about it at some point.
>
> > Dscho, do you remember details?
>
> He told me that the 'git config' code is so horrible that it's
> nigh-impossible to change the behavior, hence why he didn't do it :P.
Actually, I said something about the most obvious route being to re-use
git_config() and that this approach had its limitations.
I also said that I earned (probably rightfully) a reputation of lousy code
with Junio, which makes me think that I probably should refrain from ever
contributing code to Git again.
Ciao,
Dscho
^ permalink raw reply
* Re: [RFC/PATCHv10 01/11] fast-import: Proper notes tree manipulation
From: Shawn O. Pearce @ 2009-12-08 2:01 UTC (permalink / raw)
To: Johan Herland; +Cc: git, gitster
In-Reply-To: <200912080244.30390.johan@herland.net>
Johan Herland <johan@herland.net> wrote:
> > If we're here, isn't it likely that *all* notes are in the wrong
> > path in the tree, and we need to move them all to a new location?
> > If that's true then should we instead just build an entirely new
> > tree and swap the root when we are done?
>
> Hmm. Not always. In your earlier scenario where we add 2,000,000 notes in a
> single commit, the current code would need to rewrite 255 of them from
> fanout 0 to fanout 2, and 65,535 of them from fanout 1 to fanout 2. But the
> vast majority (1,934,465) would not require rewriting (having been added at
> the correct fanout initially). However, if we build a new tree (by which I
> assume you mean tree_content_remove() from the old tree and
> tree_content_set() to the new tree for every single note (and non-note)), we
> end up processing all 2,000,000 entries.
Well, by processing here you mean we wind up looking at them, only
to determine they are in the correct place already and skipping past.
I guess I see your point though. We're fairly bounded on how many
we might need to move, probably only 65,535, and the rest will be
at the right position so we're mostly just iterating through to
confirm they don't have to be moved.
> I'm not sure I get the details here. How can we avoid doing the
> _remove()/_set() from/to the old/new tree for every tree_entry? In other
> words, how do we avoid removing and re-setting the 2,000,000 notes in the
> above example?
You can't. But I realize now what you are saying... for the vast
majority of the notes we only need to validate they are in the
correct path.
--
Shawn.
^ permalink raw reply
* Re: [RFC/PATCHv10 01/11] fast-import: Proper notes tree manipulation
From: Johan Herland @ 2009-12-08 2:34 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, spearce
In-Reply-To: <7vocma1ppc.fsf@alter.siamese.dyndns.org>
On Monday 07 December 2009, Junio C Hamano wrote:
> Johan Herland <johan@herland.net> writes:
> > This patch teaches 'git fast-import' to automatically organize note
> > objects in a fast-import stream into an appropriate fanout structure.
>
> I really hate to sound like a clueless newbie, but that is what I am in
> the area of 'notes', so I have two questions.
>
> - What is the semantics of having more than one note to the same commit
> in the input stream? Does the 'notes' part also have history and the
> latest one overwrite the earlier one by creating a new commit that
> points at the new 'notes' tree?
Yes.
> I've always thought of 'notes' as an
> unversioned metainfo, but I realize that versioning them would make
> sense (you can and obviously would want to inspect the story behind
> the current note attached to one particular commit).
Correct. Since the notes themselves are organized in a regular ref pointing
to a series of commits, the notes for a particular object are indeed
versioned. Thus, the first annotation of a commit will happen as part of a
commit to the notes ref at some point in time, and a change to that
annotation will happen as part of a subsequent commit to the same notes ref
at some later point in time. The latter annotation naturally replaces the
former, in the same way as a regular file change causes a new blob to
replace any blob representing the previous version of the same file.
However, if some object is annotated _twice_ in the _same_ notes commit,
then only the last annotation will be reachable. (again, this is the same
behaviour as if a regular file is changed twice in the same commit).
> - If however 'notes' want to have a history, how would it interact with
> this rebalancing of the tree? Rebalancing makes a lot of sense if the
> 'notes' mechanism deals with the only one latest version because it
> can keep the optimal look-up performance. There were some talks about
> specialized merge strategies that can be made aware of rebalancing, but
> is there a plan to deal with "git log -p notes" side, and how?
For now (at least), most use cases concern themselves only with the last
version of the notes tree, hence no work has been put into prettifying the
history of the notes tree.
The notes rebalancing will become part of the same notes commit as the note
addition/removal that triggers the rebalancing. This does indeed make the
notes commits themselves somewhat uglier, but since the rebalancing only
moves notes verbatim from one location to another, it's still fairly simple
(with judicious use of e.g. "-M") to find the "actual" changes in a notes
commit.
For now, there is no plan to prettify the log of a notes ref, in order to
mask away the fanout restructuring. For that matter, there is also no plan
to hide the fanout structure itself of the notes tree. It is assumed that if
you need to look at a notes tree directly, you can either deal with the
implementation details yourself, (or by using future extensions to the notes
API; see later patches for the beginnings of those...).
With regards to specialized merge strategies: When merging two notes trees
with no specialized strategy, you might end up with two (or more) notes
objects annotating the _same_ commit (located at different fanout levels).
However, this has already been taken care of by the concatenation code at
the tail of the already-merged early part of jh/notes, which automatically
concatenates (non-identical) note objects annotating the same commit. Thus,
no special merge strategy is needed in order to administer notes trees.
Hope this helps,
...Johan
--
Johan Herland, <johan@herland.net>
www.herland.net
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox