* Re: An alternate model for preparing partial commits
From: David Jeske @ 2008-06-27 20:29 UTC (permalink / raw)
To: Robert Anderson; +Cc: Git Mailing List
In-Reply-To: <9af502e50806262350t6e794a92g7751147f1882965@mail.gmail.com>
Robert, I'm new to git, but I understand where you are going.
Why limit it only to working tree changes? For me, the stash machinery is of no
help here, because I commit super-often. What I end up with is 30 commits in a
topic branch, but where not every point passes 100% of tests. I want to go back
through and order them properly, and decide which points are sensible as
upstream committs. (especially as I read more about bisect).
git has all the concepts I want except one. However, it makes the process
pretty manual. Here is an idea about automating it. I'll talk about that one
new concept at the bottom.
I think of this as reorder/merge/split...
reorder: Picture that a list of commits on this branch opens in an editor. You
are free to rearrange the lines in any order you want, but you have to keep all
the lines. When you are done reordering the lines, the tool creates a new topic
branch and applies the changes (probably with cherrypick) to the new topic
branch. If there are no conflicts, you're done.
merge: Picture now that in your editor you can create groupings of those
individual commits that should make up separate topic-branches. The operation
can still be performed automatically, and at the end, it can compose those
topic branches into a single branch just like your original. At this point, you
can "isolate" any one of those topic branches and test/push that topic branch.
split: Picture now that you can list the same commit in more than one of the
topic-branches. This is a little more tricky, and there is no way to do it
automatically.. It drops you into an editor and asks you to select the lines of
the diff for the first topic. The remaining lines are put in the next topic.
This can continue for multiple topics.
This seems like something that could be assembled pretty easily on top of the
current git mechanisms, except for one thing.
If you use merge, the history will be a mess. If you use rebase, anyone else
who pulled your topic branch will be in a world of hurt.
I've been thinking about a solution for this I think of as "supercede".
Once you have completed the above reorder/merge/split, your new topic branch
should be EXACTLY the same as your old topic branch. (if it's not, it needs to
be trued up to be so). At that point, it is safe to ask for that new line of
commits to supercede the old line. Other people who have pulled in your older
ordered topic branch would then be able to pull/rebase/etc, and the merge
machinery would be able to back out their set of changes, and supercede them
with your new ordering.
This mechanism is intended to combine the benefits of rebase-clean-history and
the benefits of the dag-links for merging. I find it convenient to think of it
as stack push/pop for portions of the dag. Because of the supercede - the
history knows it can avoid showing you all the superceded dag nodes, however,
because those nodes are there, it can still use them to compute merges.
If this behaves the way I think, this has another powerful effect. You can pull
in a set of draft changes; you can build off them; you can periodically rebase
them, and if those draft changes end up in the mainline, because the
merge-history is still there, git can 'do the right thing' and remove those
changes from your topic branch. In fact, because of the SHA1 strong naming, it
doesn't even matter where you got them from. You could apply a patch from the
mailing list and as long as everyone applies that patch as only a single
commit, when the string of supercedes shows up on the main branch git will just
'do-the right thing' to remove them from your topic branch when you rebase (or
skip them during a merge down to your topic branch).
^ permalink raw reply
* Re: An alternate model for preparing partial commits
From: David Jeske @ 2008-06-27 20:29 UTC (permalink / raw)
To: Robert Anderson; +Cc: Git Mailing List
In-Reply-To: <9af502e50806262350t6e794a92g7751147f1882965@mail.gmail.com>
Robert, I'm new to git, but I understand where you are going.
Why limit it only to working tree changes? For me, the stash machinery is of no
help here, because I commit super-often. What I end up with is 30 commits in a
topic branch, but where not every point passes 100% of tests. I want to go back
through and order them properly, and decide which points are sensible as
upstream committs. (especially as I read more about bisect).
git has all the concepts I want except one. However, it makes the process
pretty manual. Here is an idea about automating it. I'll talk about that one
new concept at the bottom.
I think of this as reorder/merge/split...
reorder: Picture that a list of commits on this branch opens in an editor. You
are free to rearrange the lines in any order you want, but you have to keep all
the lines. When you are done reordering the lines, the tool creates a new topic
branch and applies the changes (probably with cherrypick) to the new topic
branch. If there are no conflicts, you're done.
merge: Picture now that in your editor you can create groupings of those
individual commits that should make up separate topic-branches. The operation
can still be performed automatically, and at the end, it can compose those
topic branches into a single branch just like your original. At this point, you
can "isolate" any one of those topic branches and test/push that topic branch.
split: Picture now that you can list the same commit in more than one of the
topic-branches. This is a little more tricky, and there is no way to do it
automatically.. It drops you into an editor and asks you to select the lines of
the diff for the first topic. The remaining lines are put in the next topic.
This can continue for multiple topics.
This seems like something that could be assembled pretty easily on top of the
current git mechanisms, except for one thing.
If you use merge, the history will be a mess. If you use rebase, anyone else
who pulled your topic branch will be in a world of hurt.
I've been thinking about a solution for this I think of as "supercede".
Once you have completed the above reorder/merge/split, your new topic branch
should be EXACTLY the same as your old topic branch. (if it's not, it needs to
be trued up to be so). At that point, it is safe to ask for that new line of
commits to supercede the old line. Other people who have pulled in your older
ordered topic branch would then be able to pull/rebase/etc, and the merge
machinery would be able to back out their set of changes, and supercede them
with your new ordering.
This mechanism is intended to combine the benefits of rebase-clean-history and
the benefits of the dag-links for merging. I find it convenient to think of it
as stack push/pop for portions of the dag. Because of the supercede - the
history knows it can avoid showing you all the superceded dag nodes, however,
because those nodes are there, it can still use them to compute merges.
If this behaves the way I think, this has another powerful effect. You can pull
in a set of draft changes; you can build off them; you can periodically rebase
them, and if those draft changes end up in the mainline, because the
merge-history is still there, git can 'do the right thing' and remove those
changes from your topic branch. In fact, because of the SHA1 strong naming, it
doesn't even matter where you got them from. You could apply a patch from the
mailing list and as long as everyone applies that patch as only a single
commit, when the string of supercedes shows up on the main branch git will just
'do-the right thing' to remove them from your topic branch when you rebase (or
skip them during a merge down to your topic branch).
^ permalink raw reply
* Re: An alternate model for preparing partial commits
From: Stephen Sinclair @ 2008-06-27 20:31 UTC (permalink / raw)
To: Git Mailing List
In-Reply-To: <9af502e50806271014l661dcfc9o4f61ee2b54677bd6@mail.gmail.com>
Hello,
On Fri, Jun 27, 2008 at 1:14 PM, Robert Anderson <rwa000@gmail.com> wrote:
> On Fri, Jun 27, 2008 at 6:33 AM, Johannes Schindelin
> <Johannes.Schindelin@gmx.de> wrote:
>> Now, this is not necessarily what everybody wants, which is why many
>> people are fine with the index.
>
> But it is something they should want, and should have, if they care
> about the quality of their commits. Especially in the common case of
> a project with development lines which have some sort of policy about
> build/test requirements. How do you ensure your commits obey that
> policy if you cannot verify it? That is why the index is not a
> sufficient mechanism for preparing partial commits. It's fine for
> quick and dirty operation when the factorization of the conflated
> changes is obvious and trivial. It is not sufficient otherwise.
I just thought I'd throw in my $0.02 here. There's something
fundamental I think I'm not getting about this argument: it seems to
be based on the premise that partial commits allow untested tree
states to enter the repository. However, having gotten used to the
git way of things, I personally don't see the problem with allowing
bad commits, as long as they are not pushed to public.
That is, I use the git add -p command all the time when I realize I've
just done two things that should be committed separately. Then I'll
git commit everything else, and go back and test, like so:
git checkout master
[hack hack..]
git add -p
git commit
git commit -a
[test..]
git checkout master^
[test..]
git checkout master
See? All tested. If I find a problem during testing, I'll probably
commit it and then rebase master off my new commit, fixing any
conflicts I just introduced.
Frankly I hardly even use the stash; since history can be edited, I
feel like commits are all I need when working with git. Anything I do
doesn't matter until I push to public anyways. So it's up to me to
make sure I test everything before pushing, but otherwise I'm very
happy with the ability to commit half-baked ideas and then go back to
make sure they are usable (and tested!) before pushing. This is what
local branches are for, isn't it?
Steve
^ permalink raw reply
* [RFC/PATCH] Documentation: Don't assume git-sh-setup and git-parse-remote are in the PATH
From: Jonathan Nieder @ 2008-06-27 20:10 UTC (permalink / raw)
To: git
Starting with Git 1.5.4, use of dashed forms of git commands in
scripts without "PATH=$(git --exec-path):$PATH" was deprecated. Thus
we generally advertise the non-dashed forms of commands. git-sh-setup
and git-parse-remote do not have non-dashed forms because they are
meant to be sourced from a script using .; thus the only recommended
way to use them is by updating PATH first. This patch changes the
documentation accordingly.
This does not matter as much for releases before 1.6.0, because
by default the GIT_EXEC_PATH is in the PATH already.
Signed-off-by: Jonathan Nieder <jrnieder@uchicago.edu>
---
I wrote:
> I wanted to just change the ". git-sh-setup" line to ". git sh-setup",
> but of course that will not work. Am I missing something?
Yes, I am.
I do not have asciidoc installed, so this patch is completely untested.
Documentation/git-parse-remote.txt | 2 ++
Documentation/git-sh-setup.txt | 3 ++-
2 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/Documentation/git-parse-remote.txt b/Documentation/git-parse-remote.txt
index 951dbd6..56d0505 100644
--- a/Documentation/git-parse-remote.txt
+++ b/Documentation/git-parse-remote.txt
@@ -8,6 +8,8 @@ git-parse-remote - Routines to help parsing remote repository access
SYNOPSIS
--------
+[verse]
+'PATH=$(git --exec-path):$PATH'
'. git-parse-remote'
DESCRIPTION
diff --git a/Documentation/git-sh-setup.txt b/Documentation/git-sh-setup.txt
index c543170..95b0c13 100644
--- a/Documentation/git-sh-setup.txt
+++ b/Documentation/git-sh-setup.txt
@@ -7,7 +7,8 @@ git-sh-setup - Common git shell script setup code
SYNOPSIS
--------
-'git-sh-setup'
+'PATH=$(git --exec-path):$PATH'
+'. git-sh-setup'
DESCRIPTION
-----------
--
1.5.5.GIT
^ permalink raw reply related
* Re: 'next' will be rewound shortly
From: Miklos Vajna @ 2008-06-27 19:28 UTC (permalink / raw)
To: Stephan Beyer; +Cc: Junio C Hamano, git
In-Reply-To: <20080627171948.GC6201@leksak.fem-net>
[-- Attachment #1: Type: text/plain, Size: 715 bytes --]
On Fri, Jun 27, 2008 at 07:19:48PM +0200, Stephan Beyer <s-beyer@gmx.net> wrote:
> -m <msg>::
> The commit message to be used for the merge commit (in case
> it is created). The `git-fmt-merge-msg` script can be used
> to give a good default for automated `git-merge` invocations.
>
> So it is not mentioned that a standard message is appended, and thus the
> original behavior is somehow "buggy" :)
Ah, OK. Then the code and the documentation differs and that's a bug,
sure.
From git-merge.sh:
# All the rest are the commits being merged; prepare
# the standard merge summary message to be appended to
# the given message.
I did builtin-merge based on git-merge.sh, not the manpage. ;-)
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* Ramifications of a git-sh-setup outside the PATH
From: Jonathan Nieder @ 2008-06-27 19:00 UTC (permalink / raw)
To: git
Hi gitsters,
I noticed in the release notes to Git 1.6.0 that dashed-form commands
are moving to a libexecdir outside the PATH. I have been using Git
with nd/dashless applied for about a month, and it does work well
(thanks!). There was one little glitch: to use hg-fast-export.sh from
fast-export.git (of repo.or.cz), I had to put git-sh-setup in the PATH.
I wanted to just change the ". git-sh-setup" line to ". git sh-setup",
but of course that will not work. Am I missing something?
hg-fast-export uses git-sh-setup to handle --help, to provide the
cd_to_toplevel function, and to set GIT_DIR. It would not take much
work to avoid using git-sh-setup, although for my needs it was easier
to put git-sh-setup in the PATH. But really, the use of git-sh-setup
does not seem strange to me at all. Is use of git-sh-setup in scripts
outside Git core discouraged?
The location of git-sh-setup was discussed before in the thread
<http://thread.gmane.org/gmane.comp.version-control.git/33708>.
Thanks for your time, and thank you for Git!
Sincerely,
Jonathan
^ permalink raw reply
* Re: update-index --assume-unchanged doesn't make things go fast
From: Avery Pennarun @ 2008-06-27 18:51 UTC (permalink / raw)
To: Dana How; +Cc: Jakub Narebski, Stephen R. van den Berg, Git Mailing List
In-Reply-To: <56b7f5510806271109p58b4ce47ucdcd382faa463015@mail.gmail.com>
On 6/27/08, Dana How <danahow@gmail.com> wrote:
> It sounds sane to me b/c I had the same reaction to this discussion.
> You mean "all the files in the _worktree_" ?
> You would use e.g. inotify on all the directories except .git?
> This would be very helpful with an extremely large number of files.
Yes, that's the idea. In Win32, it would use something other than
inotify, but otherwise it should work about the same.
Avery
^ permalink raw reply
* Re: An alternate model for preparing partial commits
From: Robert Anderson @ 2008-06-27 18:43 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Johannes Schindelin, Git Mailing List
In-Reply-To: <7vprq2rbfz.fsf@gitster.siamese.dyndns.org>
On Fri, Jun 27, 2008 at 11:15 AM, Junio C Hamano <gitster@pobox.com> wrote:
> I've always said that I am not in favor of any form of partial commits,
> exactly for the reason Robert states, namely that you are not committing
> what you had in your work tree as a whole. I said so back when the only
> form of partial commits were "git commit [-o] this-file". I said it again
> even when I introduced "add -i", that the interface goes backwards and
> does not fix the issues associated with partial commits.
We are seeing eye-to-eye here.
> But I agree with you that calling the index half-baked is missing the
> point.
What I said is that the index is a half-baked version of _what I
want_, which is the ability to do partial commits from testable
states. Clearly the index is a way to do partial commits, but it does
not address the "untested state" issue, so it is only halfway there,
i.e., half-baked.
> The index is merely the lowest level of facility to stage what is
> to be committed, and there is no half nor full bakedness to it. The way
> the current Porcelain layer uses it however could be improved and Robert
> is allowed to call _that_ half-baked when he is in a foul mood (even then
> I would rather prefer people to be civil on this list).
Fair enough. I did not mean "half baked" to be particular provocative, fwiw.
> I would actually go the other way. I think the problem we are trying to
> solve here in this thread is to support this (other) workflow:
>
> You keep working, and eventually build all the changes intermixed in
> your work tree, perhaps without any commit, or perhaps with a commit
> sequence that is only meant as snapshots and not as a logical
> sequence. Your work tree state is in good shape right now (you do
> build and test at this "commit goal" state). Now you would want to
> split the changes while making sure each step is good (i.e. builds and
> tests fine as well as the patch makes sense standalone).
>
> One thing I think would make sense is to stash away _everything_ at this
> point. That would take you to the state before you started working. Then
> if we can selectively _unstash_ the parts that should logically be
> committed first to bring them to your work tree, then you can inspect that
> change against HEAD, test it, and when you are happy with it, you would
> make your first commit in the final sequence.
Exactly. That was a good summary of the workflow I proposed in my
original email.
> Once you have capability to unstash selectively and make that first commit
> in the final sequence like so, breaking up the remainder that is still in
> your stash to a reasonable sequence of commits can be done with the same
> workflow. Unstash the next batch, inspect, test and be satisfied and then
> commmit. Lather, rinse and repeat.
Bingo.
Time permitting, I will propose a more well thought through UI for
this workflow. If you like it, we can talk about how it might be
implemented.
Thanks,
Bob
^ permalink raw reply
* Re: can you push from a bare repository??
From: Doug Reiland @ 2008-06-27 18:41 UTC (permalink / raw)
To: Jon Loeliger; +Cc: git
In-Reply-To: <48652F01.4080309@freescale.com>
Is that the only way? It wouldn't work for what I want to do.
I will have many users creating these environments and I wouldn't want
them all creating those remote branches on the main server.
On Fri, Jun 27, 2008 at 2:18 PM, Jon Loeliger <jdl@freescale.com> wrote:
> Doug Reiland wrote:
>>
>> I have a main repository called main
>> I create a bare clone from main call bare_clone
>> I create clone from bare_clone called work_repository_1
>>
>> I do my work in work_repository_1, commit, and push changes to bare_clone
>>
>> How to a push the changes in bare_clone into main??
>>
>
> Go to your main repo and configure up a new remote
> using "git remote add' pointing to the bare repo.
> Then fetch from that remote!
>
> jdl
>
^ permalink raw reply
* [PATCH] git-apply doesn't handle same name patches well [V4]
From: Don Zickus @ 2008-06-27 18:39 UTC (permalink / raw)
To: git; +Cc: Don Zickus
When working with a lot of people who backport patches all day long, every
once in a while I get a patch that modifies the same file more than once
inside the same patch. git-apply either fails if the second change relies
on the first change or silently drops the first change if the second change
is independent.
The silent part is the scary scenario for us. Also this behaviour is
different from the patch-utils.
I have modified git-apply to create a table of the filenames of files it
modifies such that if a later patch chunk modifies a file in the table it
will buffer the previously changed file instead of reading the original file
from disk.
Logic has been put in to handle creations/deletions/renames/copies. All the
relevant tests of git-apply succeed.
A new test has been added to cover the cases I addressed.
The fix is relatively straight-forward.
Signed-off-by: Don Zickus <dzickus@redhat.com>
---
Changes since v3
================
various improvements based on suggestions from Junio
*NOTE* I'm not entirely sure I got the mode bits right and the cache/index
stuff correct. It seems to work correctly but I didn't test every
permutation.
- simplified check_patch() using new mechanisms
- re-used mode bits if lookup succeeds in check_preimage
- add test to verify A->B, C->A, A->A works
- cheap memset hack to deal with pointers to free'd memory
- rename fn_cache to fn_table
- hours lost chasing down weird behaviour from test results :)
Changes since v2
================
- the updated patch not a v1 copy (doh!)
Changes since v1
================
- converted to path-list structs
- added testcases for renaming a patch and apply a new patch on top inside
the same patch file
---
builtin-apply.c | 82 +++++++++++++++++++++++++++++++++++++++-----
t/t4127-apply-same-fn.sh | 85 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 157 insertions(+), 10 deletions(-)
create mode 100755 t/t4127-apply-same-fn.sh
diff --git a/builtin-apply.c b/builtin-apply.c
index c497889..34ab637 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -12,6 +12,7 @@
#include "blob.h"
#include "delta.h"
#include "builtin.h"
+#include "path-list.h"
/*
* --check turns on checking that the working tree matches the
@@ -185,6 +186,13 @@ struct image {
struct line *line;
};
+/*
+ * Caches patch filenames to handle the case where a
+ * patch chunk reuses a filename
+ */
+
+static struct path_list fn_table;
+
static uint32_t hash_line(const char *cp, size_t len)
{
size_t i;
@@ -2176,15 +2184,62 @@ static int read_file_or_gitlink(struct cache_entry *ce, struct strbuf *buf)
return 0;
}
+static struct patch *in_fn_table(const char *name)
+{
+ struct path_list_item *item;
+
+ if (name == NULL)
+ return NULL;
+
+ item = path_list_lookup(name, &fn_table);
+ if (item != NULL)
+ return (struct patch *)item->util;
+
+ return NULL;
+}
+
+static void add_to_fn_table(struct patch *patch)
+{
+ struct path_list_item *item;
+
+ /*
+ * Always add new_name unless patch is a deletion
+ * This should cover the cases for normal diffs,
+ * file creations and copies
+ */
+ if (patch->new_name != NULL) {
+ item = path_list_insert(patch->new_name, &fn_table);
+ item->util = patch;
+ }
+
+ /*
+ * store a failure on rename/deletion cases because
+ * later chunks shouldn't patch old names
+ */
+ if ((patch->new_name == NULL) || (patch->is_rename)) {
+ item = path_list_insert(patch->old_name, &fn_table);
+ item->util = (struct patch *) -1;
+ }
+}
+
static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *ce)
{
struct strbuf buf;
struct image image;
size_t len;
char *img;
+ struct patch *tpatch;
strbuf_init(&buf, 0);
- if (cached) {
+
+ if ((tpatch = in_fn_table(patch->old_name)) != NULL) {
+ if (tpatch == (struct patch *) -1) {
+ return error("patch %s has been renamed/deleted",
+ patch->old_name);
+ }
+ /* We have a patched copy in memory use that */
+ strbuf_add(&buf, tpatch->result, tpatch->resultsize);
+ } else if (cached) {
if (read_file_or_gitlink(ce, &buf))
return error("read of %s failed", patch->old_name);
} else if (patch->old_name) {
@@ -2211,6 +2266,7 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *
return -1; /* note with --reject this succeeds. */
patch->result = image.buf;
patch->resultsize = image.len;
+ add_to_fn_table(patch);
free(image.line_allocated);
if (0 < patch->is_delete && patch->resultsize)
@@ -2255,6 +2311,7 @@ static int verify_index_match(struct cache_entry *ce, struct stat *st)
static int check_preimage(struct patch *patch, struct cache_entry **ce, struct stat *st)
{
const char *old_name = patch->old_name;
+ struct patch *tpatch;
int stat_ret = 0;
unsigned st_mode = 0;
@@ -2268,12 +2325,17 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
return 0;
assert(patch->is_new <= 0);
- if (!cached) {
+ if ((tpatch = in_fn_table(old_name)) != NULL) {
+ if (tpatch == (struct patch *) -1) {
+ return error("%s: has been deleted/renamed", old_name);
+ }
+ st_mode = tpatch->new_mode;
+ } else if (!cached) {
stat_ret = lstat(old_name, st);
if (stat_ret && errno != ENOENT)
return error("%s: %s", old_name, strerror(errno));
}
- if (check_index) {
+ if (check_index && !tpatch) {
int pos = cache_name_pos(old_name, strlen(old_name));
if (pos < 0) {
if (patch->is_new < 0)
@@ -2325,7 +2387,7 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
return 0;
}
-static int check_patch(struct patch *patch, struct patch *prev_patch)
+static int check_patch(struct patch *patch)
{
struct stat st;
const char *old_name = patch->old_name;
@@ -2342,8 +2404,7 @@ static int check_patch(struct patch *patch, struct patch *prev_patch)
return status;
old_name = patch->old_name;
- if (new_name && prev_patch && 0 < prev_patch->is_delete &&
- !strcmp(prev_patch->old_name, new_name))
+ if (in_fn_table(new_name) == (struct patch *) -1)
/*
* A type-change diff is always split into a patch to
* delete old, immediately followed by a patch to
@@ -2393,15 +2454,14 @@ static int check_patch(struct patch *patch, struct patch *prev_patch)
static int check_patch_list(struct patch *patch)
{
- struct patch *prev_patch = NULL;
int err = 0;
- for (prev_patch = NULL; patch ; patch = patch->next) {
+ while (patch) {
if (apply_verbosely)
say_patch_name(stderr,
"Checking patch ", patch, "...\n");
- err |= check_patch(patch, prev_patch);
- prev_patch = patch;
+ err |= check_patch(patch);
+ patch = patch->next;
}
return err;
}
@@ -2919,6 +2979,8 @@ static int apply_patch(int fd, const char *filename, int inaccurate_eof)
struct patch *list = NULL, **listp = &list;
int skipped_patch = 0;
+ /* FIXME - memory leak when using multiple patch files as inputs */
+ memset(&fn_table, 0, sizeof(struct path_list));
strbuf_init(&buf, 0);
patch_input_file = filename;
read_patch_file(&buf, fd);
diff --git a/t/t4127-apply-same-fn.sh b/t/t4127-apply-same-fn.sh
new file mode 100755
index 0000000..2a6ed77
--- /dev/null
+++ b/t/t4127-apply-same-fn.sh
@@ -0,0 +1,85 @@
+#!/bin/sh
+
+test_description='apply same filename'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ for i in a b c d e f g h i j k l m
+ do
+ echo $i
+ done >same_fn &&
+ cp same_fn other_fn &&
+ git add same_fn other_fn &&
+ git commit -m initial
+'
+test_expect_success 'apply same filename with independent changes' '
+ sed -i -e "s/^d/z/" same_fn &&
+ git diff > patch0 &&
+ git add same_fn &&
+ sed -i -e "s/^i/y/" same_fn &&
+ git diff >> patch0 &&
+ cp same_fn same_fn2 &&
+ git reset --hard &&
+ git-apply patch0 &&
+ diff same_fn same_fn2
+'
+
+test_expect_success 'apply same filename with overlapping changes' '
+ git reset --hard
+ sed -i -e "s/^d/z/" same_fn &&
+ git diff > patch0 &&
+ git add same_fn &&
+ sed -i -e "s/^e/y/" same_fn &&
+ git diff >> patch0 &&
+ cp same_fn same_fn2 &&
+ git reset --hard &&
+ git-apply patch0 &&
+ diff same_fn same_fn2
+'
+
+test_expect_success 'apply same new filename after rename' '
+ git reset --hard
+ git mv same_fn new_fn
+ sed -i -e "s/^d/z/" new_fn &&
+ git add new_fn &&
+ git diff -M --cached > patch1 &&
+ sed -i -e "s/^e/y/" new_fn &&
+ git diff >> patch1 &&
+ cp new_fn new_fn2 &&
+ git reset --hard &&
+ git apply --index patch1 &&
+ diff new_fn new_fn2
+'
+
+test_expect_success 'apply same old filename after rename -- should fail.' '
+ git reset --hard
+ git mv same_fn new_fn
+ sed -i -e "s/^d/z/" new_fn &&
+ git add new_fn &&
+ git diff -M --cached > patch1 &&
+ git mv new_fn same_fn
+ sed -i -e "s/^e/y/" same_fn &&
+ git diff >> patch1 &&
+ git reset --hard &&
+ test_must_fail git apply patch1
+'
+
+test_expect_success 'apply A->B (rename), C->A (rename), A->A -- should pass.' '
+ git reset --hard
+ git mv same_fn new_fn
+ sed -i -e "s/^d/z/" new_fn &&
+ git add new_fn &&
+ git diff -M --cached > patch1 &&
+ git commit -m "a rename" &&
+ git mv other_fn same_fn
+ sed -i -e "s/^e/y/" same_fn &&
+ git add same_fn &&
+ git diff -M --cached >> patch1 &&
+ sed -i -e "s/^g/x/" same_fn &&
+ git diff >> patch1 &&
+ git reset --hard HEAD^ &&
+ git apply patch1
+'
+
+test_done
--
1.5.6.rc2.48.g13da
^ permalink raw reply related
* Re: [PATCH/RFC] stash: introduce 'stash save --keep-index' option
From: Junio C Hamano @ 2008-06-27 18:26 UTC (permalink / raw)
To: SZEDER Gábor
Cc: Björn Steinbrink, Robert Anderson, Git Mailing List
In-Reply-To: <20080627143715.GD6747@neumann>
SZEDER Gábor <szeder@ira.uka.de> writes:
> 'git stash save' saves local modifications to a new stash, and runs 'git
> reset --hard' to revert them to a clean index and work tree. When the
> '--keep-index' option is specified, after that 'git reset --hard' the
> previous contents of the index is restored and the work tree is updated
> to match the index. This option is useful if the user wants to commit
> only parts of his local modifications, but wants to test those parts
> before committing.
Please do not describe how it does, before what it does and what it is
good for. Here is an example:
When preparing for a partial commit (iow, committing only part of
the changes you made in your work tree), you would use various
forms of "git add" to prepare the index to a shape you think is
appropriate for committing, and finally run "git commit".
This workflow however has a flaw in that you are committing
something that you could never have tested as a whole (and without
any other modification) in your work tree.
With the new "--keep-index" option, "git stash" takes a snapshot
of your index and the work tree state, and updates the work tree
to match your index, i.e. what you are about to commit. This way,
you can commit with confidence, knowing that you are committing
what you saw (and hopefully tested) as a whole in your work tree.
After making that initial commit, "git stash pop" will bring the
work tree state back without touching the index, so you can start
the next cycle of "git add" to prepare the second batch.
I do not know if your --keep-index implementation would actually allow the
above workflow; I haven't read the patch.
^ permalink raw reply
* Re: An alternate model for preparing partial commits
From: Dana How @ 2008-06-27 18:20 UTC (permalink / raw)
To: Robert Anderson; +Cc: Johannes Schindelin, Git Mailing List, danahow
In-Reply-To: <9af502e50806271049m4015b0b7nbb1c4c94a4e1a2f4@mail.gmail.com>
On Fri, Jun 27, 2008 at 10:49 AM, Robert Anderson <rwa000@gmail.com> wrote:
> On Fri, Jun 27, 2008 at 10:45 AM, Johannes Schindelin
> <Johannes.Schindelin@gmx.de> wrote:
>> Hi,
>>
>> On Fri, 27 Jun 2008, Robert Anderson wrote:
>>
>>> On Fri, Jun 27, 2008 at 6:33 AM, Johannes Schindelin
>>> <Johannes.Schindelin@gmx.de> wrote:
>>>
>>> > On Thu, 26 Jun 2008, Robert Anderson wrote:
>>> >
>>> >> Seems to me the concept of the "index" is a half-baked version of
>>> >> what I really want, which is the ability to factor a working tree's
>>> >> changes into its constituent parts in preparation for committing
>>> >> them.
>>> >
>>> > Half-baked is probably too strong a word.
>>>
>>> It is too subtle. That the index state - which becomes the next
>>> committed state - is not available for building or testing before
>>> committing is a deep flaw.
>>>
>>> > Now, this is not necessarily what everybody wants, which is why many
>>> > people are fine with the index.
>>>
>>> But it is something they should want, and should have, if they care
>>> about the quality of their commits.
>>
>> This is too narrow-minded a view for me.
>>
>> No longer interested,
>> Dscho
>>
>
> Here's a patch to match the local culture: "It is incredible how
> stupid the idea of the index is."
>
> Clearly you should now be interested.
>
> Thanks,
> Bob
I guess I'm not interested in the over-generalizations. ;-)
But the ability to use e.g. some stash-like feature (as suggested above)
to easily make the index-state (about to be committed) fully available
for compiling/processing/testing without losing edits not yet ready
for commit is an extra feature we would use here at least some of the time.
I will admit it's currently not the "itch" at the top of my list.
Thanks,
--
Dana L. How danahow@gmail.com +1 650 804 5991 cell
^ permalink raw reply
* Re: can you push from a bare repository??
From: Jon Loeliger @ 2008-06-27 18:18 UTC (permalink / raw)
To: Doug Reiland; +Cc: git
In-Reply-To: <6844644e0806271058r738e300fxf10f50b4ad29a93c@mail.gmail.com>
Doug Reiland wrote:
> I have a main repository called main
> I create a bare clone from main call bare_clone
> I create clone from bare_clone called work_repository_1
>
> I do my work in work_repository_1, commit, and push changes to bare_clone
>
> How to a push the changes in bare_clone into main??
>
Go to your main repo and configure up a new remote
using "git remote add' pointing to the bare repo.
Then fetch from that remote!
jdl
^ permalink raw reply
* Re: An alternate model for preparing partial commits
From: Junio C Hamano @ 2008-06-27 18:15 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Robert Anderson, Git Mailing List
In-Reply-To: <alpine.DEB.1.00.0806271408290.9925@racer>
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> On Thu, 26 Jun 2008, Robert Anderson wrote:
>
>> Seems to me the concept of the "index" is a half-baked version of what
>> I really want, which is the ability to factor a working tree's changes
>> into its constituent parts in preparation for committing them.
>
> Half-baked is probably too strong a word.
>
> What you are basically asking for is to have the working directory
> as staging area, and to be able to stash away changes that are not to be
> committed.
>
> Now, this is not necessarily what everybody wants, which is why many
> people are fine with the index.
I've always said that I am not in favor of any form of partial commits,
exactly for the reason Robert states, namely that you are not committing
what you had in your work tree as a whole. I said so back when the only
form of partial commits were "git commit [-o] this-file". I said it again
even when I introduced "add -i", that the interface goes backwards and
does not fix the issues associated with partial commits.
But I agree with you that calling the index half-baked is missing the
point. The index is merely the lowest level of facility to stage what is
to be committed, and there is no half nor full bakedness to it. The way
the current Porcelain layer uses it however could be improved and Robert
is allowed to call _that_ half-baked when he is in a foul mood (even then
I would rather prefer people to be civil on this list).
So I would welcome constructive proposals to make things better.
But before going into the discussion, to be fair, I would mention that
people who are used to partial commits (perhaps inherited from their
CVS/SVN habit) defend the practice by saying that they will want to make
commit series first (with unproven separation between commit boundaries
that is inherent to the practice of making partial commits) and it is not
problem for them that their commits are not tested at commit time, because
they will test each step afterwards after they are done committing. They
can fix things up later with "rebase -i" if they find glitches.
The defense makes sense from the workflow point of view, in that batching
things up tends to make people more productive. You think of the logical
separation first and make commits without having to wait for each step to
build and test (otherwise your train of thought would be interrupted), and
then you test the final resulting sequence as a separate phase. Although
I imagine I would personally not be able to work that way comfortably, I
consider this a personal preference issue, and if some people are more
productive to work that way, it is fine to support the workflow.
But that is not a reason not to support other workflows.
> Having said that, I played with the idea of a "git stash -i", which would
> allow you to select the changes to stash away.
I would actually go the other way. I think the problem we are trying to
solve here in this thread is to support this (other) workflow:
You keep working, and eventually build all the changes intermixed in
your work tree, perhaps without any commit, or perhaps with a commit
sequence that is only meant as snapshots and not as a logical
sequence. Your work tree state is in good shape right now (you do
build and test at this "commit goal" state). Now you would want to
split the changes while making sure each step is good (i.e. builds and
tests fine as well as the patch makes sense standalone).
One thing I think would make sense is to stash away _everything_ at this
point. That would take you to the state before you started working. Then
if we can selectively _unstash_ the parts that should logically be
committed first to bring them to your work tree, then you can inspect that
change against HEAD, test it, and when you are happy with it, you would
make your first commit in the final sequence.
Once you have capability to unstash selectively and make that first commit
in the final sequence like so, breaking up the remainder that is still in
your stash to a reasonable sequence of commits can be done with the same
workflow. Unstash the next batch, inspect, test and be satisfied and then
commmit. Lather, rinse and repeat.
^ permalink raw reply
* Re: update-index --assume-unchanged doesn't make things go fast
From: Dana How @ 2008-06-27 18:09 UTC (permalink / raw)
To: Avery Pennarun
Cc: Jakub Narebski, Stephen R. van den Berg, Git Mailing List,
danahow
In-Reply-To: <32541b130806271056k4698a607r11e9fbaf9102e6f1@mail.gmail.com>
On Fri, Jun 27, 2008 at 10:56 AM, Avery Pennarun <apenwarr@gmail.com> wrote:
> On 6/27/08, Jakub Narebski <jnareb@gmail.com> wrote:
>> "Avery Pennarun" <apenwarr@gmail.com> writes:
>> > On 6/26/08, Stephen R. van den Berg <srb@cuci.nl> wrote:
>> >> Avery Pennarun wrote:
>> >>> 1) What's a sensible way to tell git to *not* opendir() specific
>> >>> directories to look for unexpected files in "git status"? (I don't
>> >>> think I know enough to implement this myself.)
>> >>
>> >> Would checking the mtime on the directory itself help?
>> >
>> > I'm guessing it would help somewhat (although not as much as not
>> > checking anything at all). However, we'd still have to check the
>> > mtime *against* something, and I don't think the index stores
>> > information about directories themselves.
>>
>> By the way, from time to time there on this mailing list is idea
>> to add entries for directories in the index. This could help situation
>> like yours, tracking emty directories, faster operations when some trees
>> are unchanged, subtree <-> subproject changes.
>>
>> But it always comes back to: 1.) no proposed implementation, 2.) "git
>> tracks contents"...
>
> Yes, I've seen the occasional discussions about this.
>
> I might volunteer to help solve (1) except that I have a feeling that
> changing the index format would mangle all sorts of things beyond my
> current understanding. Attaining that understanding might not be so
> bad, except for (2), which seems like any proposed changes will
> probably be rejected anyhow.
>
> So naturally I was hoping for a magical alternative suggestion for my
> current problem instead :) One option I'm thinking about is to have
> my proposed daemon keep its own "index", which tracks *all* the files
> on the filesystem, not just the ones that have been
> git-update-index'd. Then anything that needs to compare against the
> filesystem can choose to compare against the contents of this file
> instead if it exists (and/or the right option is set, etc). Does that
> sound sane?
It sounds sane to me b/c I had the same reaction to this discussion.
You mean "all the files in the _worktree_" ?
You would use e.g. inotify on all the directories except .git?
This would be very helpful with an extremely large number of files.
Thanks,
--
Dana L. How danahow@gmail.com +1 650 804 5991 cell
^ permalink raw reply
* Re: An alternate model for preparing partial commits
From: Robert Anderson @ 2008-06-27 18:07 UTC (permalink / raw)
To: Git Mailing List
In-Reply-To: <alpine.DEB.1.00.0806271854120.9925@racer>
On Fri, Jun 27, 2008 at 10:54 AM, Johannes Schindelin
<Johannes.Schindelin@gmx.de> wrote:
> Hi,
>
> On Fri, 27 Jun 2008, Robert Anderson wrote:
>
>> Here's a patch to match the local culture: "It is incredible how stupid
>> the idea of the index is."
>>
>> Clearly you should now be interested.
>
> No, you're wrong. I am totall uninterested in talking to you now.
>
Tongue in cheek, of course - a play on Linus' "narrow minded views"
about svn. Not much of a sense of humor, eh?
You may consider the idea that the next committed state ought to be
available for build/test to be a "narrow-minded" view. I find it to
be a manifestly sound view. In fact, if you disagree I have little
respect for your technical judgment and therefore am not concerned if
you will not talk with me. Which is too bad on both counts.
Thanks,
Bob
^ permalink raw reply
* can you push from a bare repository??
From: Doug Reiland @ 2008-06-27 17:58 UTC (permalink / raw)
To: git
I have a main repository called main
I create a bare clone from main call bare_clone
I create clone from bare_clone called work_repository_1
I do my work in work_repository_1, commit, and push changes to bare_clone
How to a push the changes in bare_clone into main??
thanks in advance,
Doug
^ permalink raw reply
* Re: update-index --assume-unchanged doesn't make things go fast
From: Avery Pennarun @ 2008-06-27 17:56 UTC (permalink / raw)
To: Jakub Narebski; +Cc: Stephen R. van den Berg, Git Mailing List
In-Reply-To: <m3lk0qiy2i.fsf@localhost.localdomain>
On 6/27/08, Jakub Narebski <jnareb@gmail.com> wrote:
> "Avery Pennarun" <apenwarr@gmail.com> writes:
> > On 6/26/08, Stephen R. van den Berg <srb@cuci.nl> wrote:
> >> Avery Pennarun wrote:
> >>> 1) What's a sensible way to tell git to *not* opendir() specific
> >>> directories to look for unexpected files in "git status"? (I don't
> >>> think I know enough to implement this myself.)
> >>
> >> Would checking the mtime on the directory itself help?
> >
> > I'm guessing it would help somewhat (although not as much as not
> > checking anything at all). However, we'd still have to check the
> > mtime *against* something, and I don't think the index stores
> > information about directories themselves.
>
> By the way, from time to time there on this mailing list is idea
> to add entries for directories in the index. This could help situation
> like yours, tracking emty directories, faster operations when some trees
> are unchanged, subtree <-> subproject changes.
>
> But it always comes back to: 1.) no proposed implementation, 2.) "git
> tracks contents"...
Yes, I've seen the occasional discussions about this.
I might volunteer to help solve (1) except that I have a feeling that
changing the index format would mangle all sorts of things beyond my
current understanding. Attaining that understanding might not be so
bad, except for (2), which seems like any proposed changes will
probably be rejected anyhow.
So naturally I was hoping for a magical alternative suggestion for my
current problem instead :) One option I'm thinking about is to have
my proposed daemon keep its own "index", which tracks *all* the files
on the filesystem, not just the ones that have been
git-update-index'd. Then anything that needs to compare against the
filesystem can choose to compare against the contents of this file
instead if it exists (and/or the right option is set, etc). Does that
sound sane?
Have fun,
Avery
^ permalink raw reply
* Re: An alternate model for preparing partial commits
From: Robert Anderson @ 2008-06-27 17:49 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Git Mailing List
In-Reply-To: <alpine.DEB.1.00.0806271844230.9925@racer>
On Fri, Jun 27, 2008 at 10:45 AM, Johannes Schindelin
<Johannes.Schindelin@gmx.de> wrote:
> Hi,
>
> On Fri, 27 Jun 2008, Robert Anderson wrote:
>
>> On Fri, Jun 27, 2008 at 6:33 AM, Johannes Schindelin
>> <Johannes.Schindelin@gmx.de> wrote:
>>
>> > On Thu, 26 Jun 2008, Robert Anderson wrote:
>> >
>> >> Seems to me the concept of the "index" is a half-baked version of
>> >> what I really want, which is the ability to factor a working tree's
>> >> changes into its constituent parts in preparation for committing
>> >> them.
>> >
>> > Half-baked is probably too strong a word.
>>
>> It is too subtle. That the index state - which becomes the next
>> committed state - is not available for building or testing before
>> committing is a deep flaw.
>>
>> > Now, this is not necessarily what everybody wants, which is why many
>> > people are fine with the index.
>>
>> But it is something they should want, and should have, if they care
>> about the quality of their commits.
>
> This is too narrow-minded a view for me.
>
> No longer interested,
> Dscho
>
Here's a patch to match the local culture: "It is incredible how
stupid the idea of the index is."
Clearly you should now be interested.
Thanks,
Bob
^ permalink raw reply
* Re: [PATCH] commit-tree: lift completely arbitrary limit of 16 parents
From: Johannes Schindelin @ 2008-06-27 17:46 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Len Brown, git
In-Reply-To: <7v7icassr8.fsf@gitster.siamese.dyndns.org>
Hi,
On Fri, 27 Jun 2008, Junio C Hamano wrote:
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
> > -static int new_parent(int idx)
> > +static void new_parent(struct commit *parent, struct commit_list **parents_p)
> > {
> > - int i;
> > - unsigned char *sha1 = parent_sha1[idx];
> > - for (i = 0; i < idx; i++) {
> > - if (!hashcmp(parent_sha1[i], sha1)) {
> > + unsigned char *sha1 = parent->object.sha1;
> > + struct commit_list *parents;
> > + for (parents = *parents_p; parents; parents = parents->next) {
> > + if (!hashcmp(parents->item->object.sha1, sha1)) {
>
> Wouldn't it be enough to compare (parents->item == parent)?
Probably, since we now use lookup_commit(). Feel free to change.
> > @@ -69,18 +63,16 @@ int cmd_commit_tree(int argc, const char **argv,
> > const char *prefix)
> >
> > check_valid(tree_sha1, OBJ_TREE);
> > for (i = 2; i < argc; i += 2) {
> > + unsigned char sha1[40];
>
> s/4/2/;
Yes, I admitted that already in response to Hannes.
Mea culpa, mea maxima culpa.
Sorry,
Dscho
^ permalink raw reply
* Re: An alternate model for preparing partial commits
From: Johannes Schindelin @ 2008-06-27 17:45 UTC (permalink / raw)
To: Robert Anderson; +Cc: Git Mailing List
In-Reply-To: <9af502e50806271014l661dcfc9o4f61ee2b54677bd6@mail.gmail.com>
Hi,
On Fri, 27 Jun 2008, Robert Anderson wrote:
> On Fri, Jun 27, 2008 at 6:33 AM, Johannes Schindelin
> <Johannes.Schindelin@gmx.de> wrote:
>
> > On Thu, 26 Jun 2008, Robert Anderson wrote:
> >
> >> Seems to me the concept of the "index" is a half-baked version of
> >> what I really want, which is the ability to factor a working tree's
> >> changes into its constituent parts in preparation for committing
> >> them.
> >
> > Half-baked is probably too strong a word.
>
> It is too subtle. That the index state - which becomes the next
> committed state - is not available for building or testing before
> committing is a deep flaw.
>
> > Now, this is not necessarily what everybody wants, which is why many
> > people are fine with the index.
>
> But it is something they should want, and should have, if they care
> about the quality of their commits.
This is too narrow-minded a view for me.
No longer interested,
Dscho
^ permalink raw reply
* Re: [PATCH 1/3] Allow git-apply to ignore the hunk headers (AKA recountdiff)
From: Johannes Schindelin @ 2008-06-27 17:43 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Thomas Rast, git, Jeff King
In-Reply-To: <7vfxr29zju.fsf@gitster.siamese.dyndns.org>
Hi,
On Tue, 24 Jun 2008, Junio C Hamano wrote:
> Thomas Rast <trast@student.ethz.ch> writes:
>
> > diff --git a/builtin-apply.c b/builtin-apply.c
> > index c497889..34c220f 100644
> > --- a/builtin-apply.c
> > +++ b/builtin-apply.c
> > @@ -153,6 +153,7 @@ struct patch {
> > unsigned int is_binary:1;
> > unsigned int is_copy:1;
> > unsigned int is_rename:1;
> > + unsigned int recount:1;
> > struct fragment *fragments;
> > char *result;
> > size_t resultsize;
>
> Why doesn't anybody find this quite wrong?
>
> What is a "struct patch"? It describes a change to a single file
> (i.e. information contained from one "diff --git" til next "diff --git"),
> groups the hunks (called "fragments") together and holds the postimage
> after applying these hunks. Is this new "recount" field a per file
> attribute?
Actually, it is not. But then, it is an attribute of the patch: it will
be recounted.
In addition, the patch would get quite large and unwieldy with "recount"
being passed between the functions, because we do not have "apply_options"
yet.
I was even briefly working on apply_options, but this would be a _huge_
patch (I had an initial working version, but given my limited time, I
could not clean it up for submission anyway, so I scrapped it).
> > + fragment->oldpos = 2;
> > + fragment->oldlines = fragment->newlines = 0;
>
> Why is this discarding the position information?
Sorry, I forgot.
> > @@ -1013,6 +1058,9 @@ static int parse_fragment(char *line, unsigned long size,
> > offset = parse_fragment_header(line, len, fragment);
> > if (offset < 0)
> > return -1;
> > + if (offset > 0 && patch->recount &&
> > + recount_diff(line + offset, size - offset, fragment))
> > + return -1;
>
> And recount should not cause parse_fragment() to fail out either. If
> you miscounted, the codepath that follows this part knows how to handle
> broken patch correctly anyway.
Okay.
> I think I've already mentioned the above two points when this was
> originally posted.
>
> Somewhat disgusted...
Sorry.
This is my updated patch (making changes to my "add -e" patch, which I
may submit later), according to your comments so far:
-- snipsnap --
[PATCH] Allow git-apply to recount the lines in a hunk (AKA recountdiff)
Sometimes, the easiest way to fix up a patch is to edit it directly, even
adding or deleting lines. Now, many people are not as divine as certain
benevolent dictators as to update the hunk headers correctly at the first
try.
So teach the tool to do it for us.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
Documentation/git-apply.txt | 7 +++-
builtin-apply.c | 76 +++++++++++++++++++++++++++++++++++++++----
2 files changed, 75 insertions(+), 8 deletions(-)
diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt
index c834763..c5ee636 100644
--- a/Documentation/git-apply.txt
+++ b/Documentation/git-apply.txt
@@ -12,7 +12,7 @@ SYNOPSIS
'git-apply' [--stat] [--numstat] [--summary] [--check] [--index]
[--apply] [--no-add] [--build-fake-ancestor <file>] [-R | --reverse]
[--allow-binary-replacement | --binary] [--reject] [-z]
- [-pNUM] [-CNUM] [--inaccurate-eof] [--cached]
+ [-pNUM] [-CNUM] [--inaccurate-eof] [--recount] [--cached]
[--whitespace=<nowarn|warn|fix|error|error-all>]
[--exclude=PATH] [--verbose] [<patch>...]
@@ -177,6 +177,11 @@ behavior:
current patch being applied will be printed. This option will cause
additional information to be reported.
+--recount::
+ Do not trust the line counts in the hunk headers, but infer them
+ by inspecting the patch (e.g. after editing the patch without
+ adjusting the hunk headers appropriately).
+
Configuration
-------------
diff --git a/builtin-apply.c b/builtin-apply.c
index c497889..c819652 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -153,6 +153,7 @@ struct patch {
unsigned int is_binary:1;
unsigned int is_copy:1;
unsigned int is_rename:1;
+ unsigned int recount:1;
struct fragment *fragments;
char *result;
size_t resultsize;
@@ -882,6 +883,57 @@ static int parse_range(const char *line, int len, int offset, const char *expect
return offset + ex;
}
+static int recount_diff(char *line, int size, struct fragment *fragment)
+{
+ int oldlines = 0, newlines = 0, ret = 0;
+
+ if (size < 1) {
+ warning("recount: ignore empty hunk");
+ return -1;
+ }
+
+ for (;;) {
+ int len = linelen(line, size);
+ size -= len;
+ line += len;
+
+ if (size < 1)
+ break;
+
+ switch (*line) {
+ case ' ': case '\n':
+ newlines++;
+ /* fall through */
+ case '-':
+ oldlines++;
+ continue;
+ case '+':
+ newlines++;
+ continue;
+ case '\\':
+ break;
+ case '@':
+ ret = size < 3 || prefixcmp(line, "@@ ");
+ break;
+ case 'd':
+ ret = size < 5 || prefixcmp(line, "diff ");
+ break;
+ default:
+ ret = -1;
+ break;
+ }
+ if (ret) {
+ warning("recount: unexpected line: %.*s",
+ (int)linelen(line, size), line);
+ return -1;
+ }
+ break;
+ }
+ fragment->oldlines = oldlines;
+ fragment->newlines = newlines;
+ return 0;
+}
+
/*
* Parse a unified diff fragment header of the
* form "@@ -a,b +c,d @@"
@@ -1013,6 +1065,8 @@ static int parse_fragment(char *line, unsigned long size,
offset = parse_fragment_header(line, len, fragment);
if (offset < 0)
return -1;
+ if (offset > 0 && patch->recount)
+ recount_diff(line + offset, size - offset, fragment);
oldlines = fragment->oldlines;
newlines = fragment->newlines;
leading = 0;
@@ -2912,7 +2966,10 @@ static void prefix_patches(struct patch *p)
}
}
-static int apply_patch(int fd, const char *filename, int inaccurate_eof)
+#define INACCURATE_EOF (1<<0)
+#define RECOUNT (1<<1)
+
+static int apply_patch(int fd, const char *filename, int options)
{
size_t offset;
struct strbuf buf;
@@ -2928,7 +2985,8 @@ static int apply_patch(int fd, const char *filename, int inaccurate_eof)
int nr;
patch = xcalloc(1, sizeof(*patch));
- patch->inaccurate_eof = inaccurate_eof;
+ patch->inaccurate_eof = !!(options & INACCURATE_EOF);
+ patch->recount = !!(options & RECOUNT);
nr = parse_chunk(buf.buf + offset, buf.len - offset, patch);
if (nr < 0)
break;
@@ -2997,7 +3055,7 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
{
int i;
int read_stdin = 1;
- int inaccurate_eof = 0;
+ int options = 0;
int errs = 0;
int is_not_gitdir;
@@ -3015,7 +3073,7 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
int fd;
if (!strcmp(arg, "-")) {
- errs |= apply_patch(0, "<stdin>", inaccurate_eof);
+ errs |= apply_patch(0, "<stdin>", options);
read_stdin = 0;
continue;
}
@@ -3115,7 +3173,11 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
continue;
}
if (!strcmp(arg, "--inaccurate-eof")) {
- inaccurate_eof = 1;
+ options |= INACCURATE_EOF;
+ continue;
+ }
+ if (!strcmp(arg, "--recount")) {
+ options |= RECOUNT;
continue;
}
if (0 < prefix_length)
@@ -3126,12 +3188,12 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
die("can't open patch '%s': %s", arg, strerror(errno));
read_stdin = 0;
set_default_whitespace_mode(whitespace_option);
- errs |= apply_patch(fd, arg, inaccurate_eof);
+ errs |= apply_patch(fd, arg, options);
close(fd);
}
set_default_whitespace_mode(whitespace_option);
if (read_stdin)
- errs |= apply_patch(0, "<stdin>", inaccurate_eof);
+ errs |= apply_patch(0, "<stdin>", options);
if (whitespace_error) {
if (squelch_whitespace_errors &&
squelch_whitespace_errors < whitespace_error) {
--
1.5.6.173.gde14c
^ permalink raw reply related
* Re: An alternate model for preparing partial commits
From: Robert Anderson @ 2008-06-27 17:34 UTC (permalink / raw)
To: Björn Steinbrink; +Cc: Git Mailing List
In-Reply-To: <20080627172701.GB15359@atjola.homenet>
On Fri, Jun 27, 2008 at 10:27 AM, Björn Steinbrink <B.Steinbrink@gmx.de> wrote:
>> Now I have my guess at the first commit as my tree state, correct?
>> What happens when I decide I need a couple of hunks from another file
>> which I missed in my first guess, and is now in the stashed state?
>> How do I get those out of the stash and into the working tree? If
>> there is no convenient way to do that, then this method is not
>> sufficient to cover the use case I am talking about.
>
> git stash pop
> eventually fix conflicts if you changed the working tree in the meantime
> go back to the "git add -p" step
>
> Björn
But that pops the entire stash, right? Inconvenient at best.
A good UI here would allow you to move pieces bidirectionally to/from
the stash at will until the desired, verifiable factorization of
changes has been achieved.
Thanks,
Bob
^ permalink raw reply
* Re: update-index --assume-unchanged doesn't make things go fast
From: Jakub Narebski @ 2008-06-27 17:31 UTC (permalink / raw)
To: Avery Pennarun; +Cc: Stephen R. van den Berg, Git Mailing List
In-Reply-To: <32541b130806271001t35eb97d2gb841e194b54f214@mail.gmail.com>
"Avery Pennarun" <apenwarr@gmail.com> writes:
> On 6/26/08, Stephen R. van den Berg <srb@cuci.nl> wrote:
>> Avery Pennarun wrote:
>>>
>>> 1) What's a sensible way to tell git to *not* opendir() specific
>>> directories to look for unexpected files in "git status"? (I don't
>>> think I know enough to implement this myself.)
>>
>> Would checking the mtime on the directory itself help?
>
> I'm guessing it would help somewhat (although not as much as not
> checking anything at all). However, we'd still have to check the
> mtime *against* something, and I don't think the index stores
> information about directories themselves.
By the way, from time to time there on this mailing list is idea
to add entries for directories in the index. This could help situation
like yours, tracking emty directories, faster operations when some trees
are unchanged, subtree <-> subproject changes.
But it always comes back to: 1.) no proposed implementation, 2.) "git
tracks contents"...
--
Jakub Narebski
Poland
ShadeHawk on #git
^ permalink raw reply
* Re: An alternate model for preparing partial commits
From: Björn Steinbrink @ 2008-06-27 17:27 UTC (permalink / raw)
To: Robert Anderson; +Cc: Git Mailing List
In-Reply-To: <9af502e50806270954q613087efub0eb05c25f2eefb9@mail.gmail.com>
On 2008.06.27 09:54:43 -0700, Robert Anderson wrote:
> On Fri, Jun 27, 2008 at 12:10 AM, Björn Steinbrink <B.Steinbrink@gmx.de> wrote:
> > Hm, I use "stash" for that purpose, which leads to kind of the reverse
> > of your approach. So I do sth. like this:
> > - hack hack hack
> > - Notice that I want to make two commits out of what I have in my
> > working tree
> > - git add -p -- stage what I want in the first commit
> > - git commit -m tmp -- temporary commit
>
> This is a guess at the first commit? I don't like it, but I'm still
> listening.
It's rather a work-around to stash away only the changes that are not in
the index. See the other reply to my mail for a patch that adds an
option to stash to do that without the commit/reset hack.
> > - git stash -- stash away what doesn't belong in the first commit
> > - git reset HEAD^ -- drop the temporary commit, with the changes kept
> > in the working tree
>
> Now I have my guess at the first commit as my tree state, correct?
> What happens when I decide I need a couple of hunks from another file
> which I missed in my first guess, and is now in the stashed state?
> How do I get those out of the stash and into the working tree? If
> there is no convenient way to do that, then this method is not
> sufficient to cover the use case I am talking about.
git stash pop
eventually fix conflicts if you changed the working tree in the meantime
go back to the "git add -p" step
Björn
^ 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