* Re: Two crazy proposals for changing git's diff commands
From: Junio C Hamano @ 2006-02-09 1:21 UTC (permalink / raw)
To: Carl Worth; +Cc: git
In-Reply-To: <87slqtcr2f.wl%cworth@cworth.org>
Carl Worth <cworth@cworth.org> writes:
> Can anyone else think of common use cases for these various
> operations that I've missed?
If there is none, then that means we have covered everything.
But a more interesting question to ask is "are there useful
comparisons that the existing diff lowlevel does not give me
with a single command". And the answer is of course yes.
For example, you cannot preview "git commit --include paths..."
with a single low-level command. You would need to run
"git-diff-index --cached HEAD" for paths that are _not_
specified, and "git-diff-index HEAD" output for paths that you
will give to "--include" when you make that commit.
> Proposal 1: Make diff-index use HEAD if no <tree> is specified
No need. "git diff --cached" does it, as you discovered. I am
open to update the lowlevel if there is a need, but this does
not justify it.
> If "git diff" is learned as a commit preview, (during a larval
> index-unaware stage), then this behavior will have to be unlearned
> when the user starts using the index. At that point "git diff" becomes
> a way to examine what will *not* be committed by "git commit" rather
> than what *will* be committed by "git commit -a".
Of course, learning various flags to give "git diff" is part of
understanding the index, so if the user understands index, "git
diff" without arguments will _not_ be the only diff command the
user uses for a preview. And I suspect that depending on what
development style you would use, the definition of "useful
comparisons" would be different.
You are assuming that the user graduated from "larval unaware"
in this part of the discussion, no?
> And I think this goes toward my which-diff confusion. Consider the
> three diff operations that allow for investigating un-committed trees:
>
> <tree> -> index diff-index --cached <tree>
> index -> files diff-files
> <tree> -> files diff-index <tree>
>
> Here, "diff-index" is the only one of the three commands that does not
> operate on the index. One can notice a similar thing in the ASCII
> diagram from the core tutorial where diff-index is the only one of
> these three operations that completely bypasses the index (!).
By the way, diff-index without --cached *does* use index.
Unindexed paths are not shown. All this means that there is
still inconsistent understanding on your part.
> Proposal #2: Provide the following 4 diff commands:
Forget about renaming the core-level commands. This is
UNNEGOTIABLE, at least with something like the reasoning
presented in your message. You need to have something stronger
than that.
I'm VERY open to give friendlier interface to 'git-diff'
wrapper, though. And I appreciate that part of your discussion
very much. The end users, once the improvement proposal like
yours is done right, should NOT need to use the lowlevel diff
command directly AT ALL, so renaming low-level serves no useful
purpose other than confusing Porcelain people and me.
> The goal here is that using diff, diff-index, and diff-files without
> any tree argument and without any options (such as --cached) should
> cover the most common cases. So there's less typing in general.
No, the goal should be for normal workflows there should be *no*
need to use lowlevel commands by end users day-to-day. Myself,
I have not typed lowlevel commands from the command line for
quite a long time, except when I am debugging, and except when I
wanted to see "diff-tree --cc" output for a single commit, only
because there was no suitable wrapper. The last reason is now
gone thanks to "git-show" Linus added. So as far as *MY*
workflow is concerned, that goal has already been achieved.
I am not saying there is something wrong with your workflow --
the tool may still not give an easier way to get a diff you
would want in your workflow. I've given one example already
about the --include commit preview. So let's concentrate on
this question:
What are the useful workflows, in which during various
phases of that workflow, existing "git diff" wrapper
does not give us a useful comparison?
Then we can fill what is lacking. During the course of this
exercise, it _might_ turn out that the low-level may need to be
updated to make generation of such an output easier and/or more
efficient, but first we need know what we want to add to the end
result. Mucking with the machinery to generate output must come
after that.
While I suspect what people would want most would be commit
previews, I purposely said "useful comparison" instead of
"commit preview" in the above. Reviewing a conflicted merge
with "git diff" falls into "useful comparison but not commit
preview" category.
Commit preview alone is rather easy. No matter how your worklow
is (one extreme being no update-index until you are ready to
commit, and say "git commit -a" to commit everything --- the
other extreme being frequent update-index between commit, even
multiple update-index on the same paths, and do "git commit
--include paths..."), there are only four ways to make commits:
$ git commit
=> git diff --cached
$ git commit -a
=> git diff HEAD
$ git commit --only paths...
=> git diff HEAD paths...
$ git commit --include paths...
... there is no support in "git diff"; it cannot be done
... with a single low-level.
So we could even implement that with
$ git commit --preview [other flags] [paths...]
and three quarters of necessary things are already there.
There are obvious two other alternatives:
$ git commit-preview [commit flags and paths...]
$ git diff --preview [commit flags and paths...]
^ permalink raw reply
* Re: Two crazy proposals for changing git's diff commands
From: Linus Torvalds @ 2006-02-09 1:21 UTC (permalink / raw)
To: Carl Worth; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0602081643570.2458@g5.osdl.org>
On Wed, 8 Feb 2006, Linus Torvalds wrote:
>
> The largest reason for why "git diff" defaults to diffing against the
> index (and not head) is _literally_ that it's faster. Yes, I'm ashamed,
> but "git diff HEAD" takes 0.35 seconds for me, and "git diff" takes 0.07
> seconds, and largely based entirely on that (and not "what would users
> want"), I made the bad choice to default to git-diff-files for the "no
> arguments" case.
>
> I hang my head in shame. I just like the _instantness_ of "nothing
> changed". That's a bad reason for choice of interfaces, though.
Btw, it was kind of luck (but it's definitely true) that the current "git
diff" semantics happen to also be what you do want during merges when you
try to resolve a conflict (while "git diff HEAD" is much less useful).
So making "git diff" default to diffing against HEAD is actually the wrong
thing to do during merging, where the current behaviour is exactly what
you'd want.
So I dunno.
Linus
^ permalink raw reply
* Re: Two crazy proposals for changing git's diff commands
From: Linus Torvalds @ 2006-02-09 1:30 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Carl Worth, git
In-Reply-To: <7vfymtl43b.fsf@assigned-by-dhcp.cox.net>
On Wed, 8 Feb 2006, Junio C Hamano wrote:
>
> So we could even implement that with
>
> $ git commit --preview [other flags] [paths...]
My argument for "git status" was that it very much _is_ about "what would
I commit". So I'd much rather extend on "git status" than add a
"--preview" flag to "git commit".
At least to me, "git status" is very much a "what is pending" kind of
command. The fact that you can't con it into giving a diff is actually a
downside: I would at times have preferred to have the "git commit" message
contain an extended status that contained the diffs too.
Another way of saying that: I think it would make sense to have a verbose
status report, and maybe also have that verbose flag passed into "git
commit" so that you can see the verbose status when you edit the commit
message.
Under that logic, "git status -v" would show all the diffs (not just
filenames) and "git commit -v .." would be the same as "git commit .." but
the "-v" flag would have been passed down to the "git status" call, so the
commit message file would be pre-populated with the diff.
For small commits, it's actually nice to see the diff itself as you write
the commit message.
Linus
^ permalink raw reply
* Re: Two crazy proposals for changing git's diff commands
From: Junio C Hamano @ 2006-02-09 1:35 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0602081643570.2458@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> In particular, I think the real culprit is the plain "git diff" with no
> arguments at all. Right now it ends up showing just a piece of the
> picture, and the piece it shows is incomplete enough to be irritating.
Not necessarily. Your "during the merge" example is a good one,
and "so far it looks good and I do not want to see these diffs
while modifying things further -- update-index it!" workflow
benefits immensely from it.
> Right now a plain "git diff" only shows the differences in the current
> tree against the index. I think that was just the wrong choice. I think
> almost everybody would actually prefer the default to be to show the
> difference against HEAD.
I somehow suspect this is welding training wheels to your
bicycle.
> Teaching "git status" to take a "-p" flag (for "patch" - or -v for
> "verbose") might actually be a good thing. Then, instead of "git diff",
> you'd use "git status -p" and it would show you what the differences are
> in the index, and what they are in the tree, so you'd _really_ know what
> "git commit" in all its glory would do.
I think this may not be a bad idea.
What we could do is this:
$ git status -v [--only | --include] [paths...]
When -v is given, it takes the same parameter as "git commit",
and changes its output format from the usual N x "# useful info lines"
to something like:
---
diff ...
--- a/path
+++ b/path
@@ -N,M +L,K @@
that shows the commit preview. At the same time we change "git
commit" commit log message reader to stop reading the input at
the first '---' line, just like we do for e-mailed patches.
Then:
- If you want a commit preview _before_ initiating a commit,
you can say:
$ git status -v [whatever you planned to give git commit]
- If you want a commit preview _while_ writing the commit log, you can
say:
$ git commit -v [whatever your parameters are]
which internally would pass the -v and "$@" to git status
that seeds the log message
- If you want a commit preview after you made a commit, it is
too late ;-).
^ permalink raw reply
* Re: Two crazy proposals for changing git's diff commands
From: Junio C Hamano @ 2006-02-09 1:37 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0602081726390.2458@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> On Wed, 8 Feb 2006, Junio C Hamano wrote:
>>
>> So we could even implement that with
>>
>> $ git commit --preview [other flags] [paths...]
>
> My argument for "git status" was that it very much _is_ about "what would
> I commit". So I'd much rather extend on "git status" than add a
> "--preview" flag to "git commit".
Our messages crossed. I'd agree about the reasoning completely,
as I did in my previous message.
Now we need to find a volunteer to do all that work ;-).
^ permalink raw reply
* Re: gitweb using "--cc"?
From: Brian Gerst @ 2006-02-09 2:13 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Kay Sievers, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0602081532360.2458@g5.osdl.org>
Linus Torvalds wrote:
> I just did an arm merge that needed some (very trivial) manual fixups
> (commit ID cce0cac1, in case anybody cares).
>
> As usual, git-diff-tree --cc does a beautiful job on it, but I also
> checked the gitweb output, which seems to not do as well (the commit
> message about a manual conflict merge doesn't make any sense at all).
>
> Now, in this case, what gitweb shows is actually "sensible": it will show
> the diff of what the merge "brought in" to the mainline kernel, and in
> that sense I can certainly understand it. It basically diffs the merge
> against the first parent.
>
> So looking at that particular example, arguably gitweb does something
> "different" from what the commit message is talking about, but in many
> ways it's a perfectly logical thing.
>
> However, diffing against the first parent, while it sometimes happens to
> be a sane thing to do, really isn't very sane in general. The merge may go
> the other way (subdevelopers merging my code), like in commit b2faf597,
> and sometimes there might not be a single reference tree, but more of a
> "couple of main branches" approach with merging back and forth). Then the
> current gitweb behaviour makes no sense at all.
>
> So it would be much nicer if gitweb had some alternate approach to showing
> merge diffs. My suggested approach would be to just let the user choose:
> have separate "diff against fist/second[/third[/..]] parent" buttons. And
> one of the choices would be the "conflict view" that git-diff-tree --cc
> gives (I'd argue for that being the default one, because it's the only one
> that doesn't have a "preferred parent").
>
> Kay?
>
> Linus
> -
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
git-whatchanged doesn't show that merge commit either.
--
Brian Gerst
^ permalink raw reply
* Re: gitweb using "--cc"?
From: Linus Torvalds @ 2006-02-09 2:26 UTC (permalink / raw)
To: Brian Gerst; +Cc: Kay Sievers, Git Mailing List
In-Reply-To: <43EAA560.8030504@didntduck.org>
On Wed, 8 Feb 2006, Brian Gerst wrote:
>
> git-whatchanged doesn't show that merge commit either.
Actually, it does. You just have to ask it.
git-whatchanged --cc
The thing is, "git-whatchanged" is different from "git diff" and other
helpers, in that it by default shows the "raw" git representation. Which
indeed doesn't show that merge as being anything interesting.
But with "--cc", the merge suddenly blossoms.
Now, arguably, the raw format should default to the same kind of "were
there data conflicts" that "-c" does for merges, but it doesn't, so it's
silent ;(
Linus
^ permalink raw reply
* Re: gitweb using "--cc"?
From: Kay Sievers @ 2006-02-09 3:13 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0602081532360.2458@g5.osdl.org>
On Wed, Feb 08, 2006 at 03:44:58PM -0800, Linus Torvalds wrote:
>
> I just did an arm merge that needed some (very trivial) manual fixups
> (commit ID cce0cac1, in case anybody cares).
>
> As usual, git-diff-tree --cc does a beautiful job on it, but I also
> checked the gitweb output, which seems to not do as well (the commit
> message about a manual conflict merge doesn't make any sense at all).
>
> Now, in this case, what gitweb shows is actually "sensible": it will show
> the diff of what the merge "brought in" to the mainline kernel, and in
> that sense I can certainly understand it. It basically diffs the merge
> against the first parent.
>
> So looking at that particular example, arguably gitweb does something
> "different" from what the commit message is talking about, but in many
> ways it's a perfectly logical thing.
>
> However, diffing against the first parent, while it sometimes happens to
> be a sane thing to do, really isn't very sane in general. The merge may go
> the other way (subdevelopers merging my code), like in commit b2faf597,
> and sometimes there might not be a single reference tree, but more of a
> "couple of main branches" approach with merging back and forth). Then the
> current gitweb behaviour makes no sense at all.
>
> So it would be much nicer if gitweb had some alternate approach to showing
> merge diffs. My suggested approach would be to just let the user choose:
> have separate "diff against fist/second[/third[/..]] parent" buttons. And
> one of the choices would be the "conflict view" that git-diff-tree --cc
> gives (I'd argue for that being the default one, because it's the only one
> that doesn't have a "preferred parent").
Hmm, I have no real clue what all the --cc is about. It's not obvious
for someone who never thought about "meta patches" or "complex merges". :)
If nobody else can do the changes to gitweb, sure, I'll do this and try
to understand what is needed, but then I will need it explained in more
details, what functionality we want to see here. At best with some commented
commandline examples that produce the data you want to see. So that I
can imagine what you are looking for and can give it a try ...
On the technical side for the kernel.org installation:
does git diff use /usr/bin/diff?
does git diff create temp files?
how can i specify the location for the temp files?
(wasn't possible some months ago, but needed on kernel.org)
is the temp file naming safe for a lot of git diff running in parallel?
is a --cc capable git already available on the kernel.org boxes?
Thanks,
Kay
^ permalink raw reply
* Re: gitweb using "--cc"?
From: Junio C Hamano @ 2006-02-09 3:14 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0602081817040.2458@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> Now, arguably, the raw format should default to the same kind of "were
> there data conflicts" that "-c" does for merges, but it doesn't, so it's
> silent ;(
True. There was a discussion to come up with a sensible
semantics for -c without -p (currently --cc and -c implies -p),
but I haven't got around to it, since --cc was more useful in
general.
Volunteers?
^ permalink raw reply
* Re: Handling large files with GIT
From: Greg KH @ 2006-02-09 4:54 UTC (permalink / raw)
To: Florian Weimer; +Cc: git
In-Reply-To: <87slqty2c8.fsf@mid.deneb.enyo.de>
On Wed, Feb 08, 2006 at 10:20:39PM +0100, Florian Weimer wrote:
> * Martin Langhoff:
>
> > SVN does reasonably well tracking his >1GB mbox file. Now, I don't
> > know if I like the idea of putting my own mbox file under version
> > control, but it looks like projects with large and slow-changing files
> > would be in trouble with GIT.
>
> To my surprise, it's not that bad. The Debian testing-security team
> uses a single 1.8 MB file (400 KB compressed) to keep vulnerability
> data. Most changes to that file involve just a few lines. But even
> in this extreme case, git doesn't compare too badly against Subversion
> if you pack regularly (but not too often). Disk usage is actually
> *below* Subversion FSFS even with --depth=10 (the default,
> unfortunately a bit hard to override).
I have a project that has 2.5Mb files, and git handles them just fine,
even on my old slow laptop.
But when I tried to use it to backup my old email archive a few months
ago, running about 2Gb in about 300 files, it took forever. Luckily I
only archive stuff off every other month or so, otherwise it would be
unusable.
However, I did notice one problem. When cloning from one machine to
another, for a project that is already fully packed, it seems that the
whole project is packed again before sending it accross the wire. With
an archive this big, that takes over an hour for my slow old fileserver.
I ended up just rsyncing over the files and pointing the parent back to
the original. Is there anyway to not repack everything if it's not
needed?
thanks,
greg k-h
^ permalink raw reply
* [PATCH] "Assume unchanged" git
From: Junio C Hamano @ 2006-02-09 5:15 UTC (permalink / raw)
To: git
Cc: Alex Riesen, Radoslaw Szkodzinski, Keith Packard, cworth,
Martin Langhoff, Linus Torvalds
In-Reply-To: <Pine.LNX.4.64.0601311807470.7301@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> The real meat is just making sure that CE_VALID gets set/cleared properly.
Setting is easier part. Deciding when to ignore/clear for the
sake of safety and usability is harder. I think I got the
basics right but we might want to pass "really" from more places.
This is _not_ 1.2 material, but I think it is ready to be tested
by people who asked for this feature. It applies on top of the
recent master branch.
-- >8 --
[PATCH] "Assume unchanged" git
This adds "assume unchanged" logic, started by this message in the list
discussion recently:
<Pine.LNX.4.64.0601311807470.7301@g5.osdl.org>
This is a workaround for filesystems that do not have lstat()
that is quick enough for the index mechanism to take advantage
of. On the paths marked as "assumed to be unchanged", the user
needs to explicitly use update-index to register the object name
to be in the next commit.
You can use two new options to update-index to set and reset the
CE_VALID bit:
git-update-index --assume-unchanged path...
git-update-index --no-assume-unchanged path...
These forms manipulate only the CE_VALID bit; it does not change
the object name recorded in the index file. Nor they add a new
entry to the index.
When the configuration variable "core.ignorestat = true" is set,
the index entries are marked with CE_VALID bit automatically
after:
- update-index to explicitly register the current object name to the
index file.
- when update-index --refresh finds the path to be up-to-date.
- when tools like read-tree -u and apply --index update the working
tree file and register the current object name to the index file.
The flag is dropped upon read-tree that does not check out the index
entry. This happens regardless of the core.ignorestat settings.
Index entries marked with CE_VALID bit are assumed to be
unchanged most of the time. However, there are cases that
CE_VALID bit is ignored for the sake of safety and usability:
- while "git-read-tree -m" or git-apply need to make sure
that the paths involved in the merge do not have local
modifications. This sacrifices performance for safety.
- when git-checkout-index -f -q -u -a tries to see if it needs
to checkout the paths. Otherwise you can never check
anything out ;-).
- when git-update-index --really-refresh (a new flag) tries to
see if the index entry is up to date. You can start with
everything marked as CE_VALID and run this once to drop
CE_VALID bit for paths that are modified.
Most notably, "update-index --refresh" honours CE_VALID and does
not actively stat, so after you modified a file in the working
tree, update-index --refresh would not notice until you tell the
index about it with "git-update-index path" or "git-update-index
--no-assume-unchanged path".
This version is not expected to be perfect. I think diff
between index and/or tree and working files may need some
adjustment, and there probably needs other cases we should
automatically unmark paths that are marked to be CE_VALID.
But the basics seem to work, and ready to be tested by people
who asked for this feature.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
apply.c | 2 +-
cache.h | 6 +++--
checkout-index.c | 1 +
config.c | 5 ++++
diff-files.c | 2 +-
diff-index.c | 2 +-
diff.c | 2 +-
entry.c | 2 +-
environment.c | 1 +
read-cache.c | 28 +++++++++++++++++++----
read-tree.c | 2 +-
update-index.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++------
write-tree.c | 2 +-
13 files changed, 99 insertions(+), 21 deletions(-)
b169290f100cfa67b785c361bcae83f807487f5e
diff --git a/apply.c b/apply.c
index 2ad47fb..35ae48e 100644
--- a/apply.c
+++ b/apply.c
@@ -1309,7 +1309,7 @@ static int check_patch(struct patch *pat
return -1;
}
- changed = ce_match_stat(active_cache[pos], &st);
+ changed = ce_match_stat(active_cache[pos], &st, 1);
if (changed)
return error("%s: does not match index",
old_name);
diff --git a/cache.h b/cache.h
index bdbe2d6..cd58fad 100644
--- a/cache.h
+++ b/cache.h
@@ -91,6 +91,7 @@ struct cache_entry {
#define CE_NAMEMASK (0x0fff)
#define CE_STAGEMASK (0x3000)
#define CE_UPDATE (0x4000)
+#define CE_VALID (0x8000)
#define CE_STAGESHIFT 12
#define create_ce_flags(len, stage) htons((len) | ((stage) << CE_STAGESHIFT))
@@ -144,8 +145,8 @@ extern int add_cache_entry(struct cache_
extern int remove_cache_entry_at(int pos);
extern int remove_file_from_cache(const char *path);
extern int ce_same_name(struct cache_entry *a, struct cache_entry *b);
-extern int ce_match_stat(struct cache_entry *ce, struct stat *st);
-extern int ce_modified(struct cache_entry *ce, struct stat *st);
+extern int ce_match_stat(struct cache_entry *ce, struct stat *st, int);
+extern int ce_modified(struct cache_entry *ce, struct stat *st, int);
extern int ce_path_match(const struct cache_entry *ce, const char **pathspec);
extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, const char *type);
extern int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object);
@@ -161,6 +162,7 @@ extern int commit_index_file(struct cach
extern void rollback_index_file(struct cache_file *);
extern int trust_executable_bit;
+extern int assume_unchanged;
extern int only_use_symrefs;
extern int diff_rename_limit_default;
extern int shared_repository;
diff --git a/checkout-index.c b/checkout-index.c
index 53dd8cb..957b4a8 100644
--- a/checkout-index.c
+++ b/checkout-index.c
@@ -116,6 +116,7 @@ int main(int argc, char **argv)
int all = 0;
prefix = setup_git_directory();
+ git_config(git_default_config);
prefix_length = prefix ? strlen(prefix) : 0;
if (read_cache() < 0) {
diff --git a/config.c b/config.c
index 8355224..7dbdce1 100644
--- a/config.c
+++ b/config.c
@@ -222,6 +222,11 @@ int git_default_config(const char *var,
return 0;
}
+ if (!strcmp(var, "core.ignorestat")) {
+ assume_unchanged = git_config_bool(var, value);
+ return 0;
+ }
+
if (!strcmp(var, "core.symrefsonly")) {
only_use_symrefs = git_config_bool(var, value);
return 0;
diff --git a/diff-files.c b/diff-files.c
index d24d11c..c96ad35 100644
--- a/diff-files.c
+++ b/diff-files.c
@@ -191,7 +191,7 @@ int main(int argc, const char **argv)
show_file('-', ce);
continue;
}
- changed = ce_match_stat(ce, &st);
+ changed = ce_match_stat(ce, &st, 0);
if (!changed && !diff_options.find_copies_harder)
continue;
oldmode = ntohl(ce->ce_mode);
diff --git a/diff-index.c b/diff-index.c
index f8a102e..12a9418 100644
--- a/diff-index.c
+++ b/diff-index.c
@@ -33,7 +33,7 @@ static int get_stat_data(struct cache_en
}
return -1;
}
- changed = ce_match_stat(ce, &st);
+ changed = ce_match_stat(ce, &st, 0);
if (changed) {
mode = create_ce_mode(st.st_mode);
if (!trust_executable_bit &&
diff --git a/diff.c b/diff.c
index ec51e7d..c72064e 100644
--- a/diff.c
+++ b/diff.c
@@ -311,7 +311,7 @@ static int work_tree_matches(const char
ce = active_cache[pos];
if ((lstat(name, &st) < 0) ||
!S_ISREG(st.st_mode) || /* careful! */
- ce_match_stat(ce, &st) ||
+ ce_match_stat(ce, &st, 0) ||
memcmp(sha1, ce->sha1, 20))
return 0;
/* we return 1 only when we can stat, it is a regular file,
diff --git a/entry.c b/entry.c
index 6c47c3a..8fb99bc 100644
--- a/entry.c
+++ b/entry.c
@@ -123,7 +123,7 @@ int checkout_entry(struct cache_entry *c
strcpy(path + len, ce->name);
if (!lstat(path, &st)) {
- unsigned changed = ce_match_stat(ce, &st);
+ unsigned changed = ce_match_stat(ce, &st, 1);
if (!changed)
return 0;
if (!state->force) {
diff --git a/environment.c b/environment.c
index 0596fc6..251e53c 100644
--- a/environment.c
+++ b/environment.c
@@ -12,6 +12,7 @@
char git_default_email[MAX_GITNAME];
char git_default_name[MAX_GITNAME];
int trust_executable_bit = 1;
+int assume_unchanged = 0;
int only_use_symrefs = 0;
int repository_format_version = 0;
char git_commit_encoding[MAX_ENCODING_LENGTH] = "utf-8";
diff --git a/read-cache.c b/read-cache.c
index c5474d4..efbb1be 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -27,6 +27,9 @@ void fill_stat_cache_info(struct cache_e
ce->ce_uid = htonl(st->st_uid);
ce->ce_gid = htonl(st->st_gid);
ce->ce_size = htonl(st->st_size);
+
+ if (assume_unchanged)
+ ce->ce_flags |= htons(CE_VALID);
}
static int ce_compare_data(struct cache_entry *ce, struct stat *st)
@@ -146,9 +149,18 @@ static int ce_match_stat_basic(struct ca
return changed;
}
-int ce_match_stat(struct cache_entry *ce, struct stat *st)
+int ce_match_stat(struct cache_entry *ce, struct stat *st, int ignore_valid)
{
- unsigned int changed = ce_match_stat_basic(ce, st);
+ unsigned int changed;
+
+ /*
+ * If it's marked as always valid in the index, it's
+ * valid whatever the checked-out copy says.
+ */
+ if (!ignore_valid && (ce->ce_flags & htons(CE_VALID)))
+ return 0;
+
+ changed = ce_match_stat_basic(ce, st);
/*
* Within 1 second of this sequence:
@@ -164,7 +176,7 @@ int ce_match_stat(struct cache_entry *ce
* effectively mean we can make at most one commit per second,
* which is not acceptable. Instead, we check cache entries
* whose mtime are the same as the index file timestamp more
- * careful than others.
+ * carefully than others.
*/
if (!changed &&
index_file_timestamp &&
@@ -174,10 +186,10 @@ int ce_match_stat(struct cache_entry *ce
return changed;
}
-int ce_modified(struct cache_entry *ce, struct stat *st)
+int ce_modified(struct cache_entry *ce, struct stat *st, int really)
{
int changed, changed_fs;
- changed = ce_match_stat(ce, st);
+ changed = ce_match_stat(ce, st, really);
if (!changed)
return 0;
/*
@@ -233,6 +245,11 @@ int cache_name_compare(const char *name1
return -1;
if (len1 > len2)
return 1;
+
+ /* Differences between "assume up-to-date" should not matter. */
+ flags1 &= ~CE_VALID;
+ flags2 &= ~CE_VALID;
+
if (flags1 < flags2)
return -1;
if (flags1 > flags2)
@@ -430,6 +447,7 @@ int add_cache_entry(struct cache_entry *
int ok_to_add = option & ADD_CACHE_OK_TO_ADD;
int ok_to_replace = option & ADD_CACHE_OK_TO_REPLACE;
int skip_df_check = option & ADD_CACHE_SKIP_DFCHECK;
+
pos = cache_name_pos(ce->name, ntohs(ce->ce_flags));
/* existing match? Just replace it. */
diff --git a/read-tree.c b/read-tree.c
index 5580f15..52f06e3 100644
--- a/read-tree.c
+++ b/read-tree.c
@@ -349,7 +349,7 @@ static void verify_uptodate(struct cache
return;
if (!lstat(ce->name, &st)) {
- unsigned changed = ce_match_stat(ce, &st);
+ unsigned changed = ce_match_stat(ce, &st, 1);
if (!changed)
return;
errno = 0;
diff --git a/update-index.c b/update-index.c
index afec98d..767fd49 100644
--- a/update-index.c
+++ b/update-index.c
@@ -23,6 +23,10 @@ static int quiet; /* --refresh needing u
static int info_only;
static int force_remove;
static int verbose;
+static int mark_valid_only = 0;
+#define MARK_VALID 1
+#define UNMARK_VALID 2
+
/* Three functions to allow overloaded pointer return; see linux/err.h */
static inline void *ERR_PTR(long error)
@@ -53,6 +57,25 @@ static void report(const char *fmt, ...)
va_end(vp);
}
+static int mark_valid(const char *path)
+{
+ int namelen = strlen(path);
+ int pos = cache_name_pos(path, namelen);
+ if (0 <= pos) {
+ switch (mark_valid_only) {
+ case MARK_VALID:
+ active_cache[pos]->ce_flags |= htons(CE_VALID);
+ break;
+ case UNMARK_VALID:
+ active_cache[pos]->ce_flags &= ~htons(CE_VALID);
+ break;
+ }
+ active_cache_changed = 1;
+ return 0;
+ }
+ return -1;
+}
+
static int add_file_to_cache(const char *path)
{
int size, namelen, option, status;
@@ -94,6 +117,7 @@ static int add_file_to_cache(const char
ce = xmalloc(size);
memset(ce, 0, size);
memcpy(ce->name, path, namelen);
+ ce->ce_flags = htons(namelen);
fill_stat_cache_info(ce, &st);
ce->ce_mode = create_ce_mode(st.st_mode);
@@ -105,7 +129,6 @@ static int add_file_to_cache(const char
if (0 <= pos)
ce->ce_mode = active_cache[pos]->ce_mode;
}
- ce->ce_flags = htons(namelen);
if (index_path(ce->sha1, path, &st, !info_only))
return -1;
@@ -128,7 +151,7 @@ static int add_file_to_cache(const char
* For example, you'd want to do this after doing a "git-read-tree",
* to link up the stat cache details with the proper files.
*/
-static struct cache_entry *refresh_entry(struct cache_entry *ce)
+static struct cache_entry *refresh_entry(struct cache_entry *ce, int really)
{
struct stat st;
struct cache_entry *updated;
@@ -137,21 +160,22 @@ static struct cache_entry *refresh_entry
if (lstat(ce->name, &st) < 0)
return ERR_PTR(-errno);
- changed = ce_match_stat(ce, &st);
+ changed = ce_match_stat(ce, &st, really);
if (!changed)
return NULL;
- if (ce_modified(ce, &st))
+ if (ce_modified(ce, &st, really))
return ERR_PTR(-EINVAL);
size = ce_size(ce);
updated = xmalloc(size);
memcpy(updated, ce, size);
fill_stat_cache_info(updated, &st);
+
return updated;
}
-static int refresh_cache(void)
+static int refresh_cache(int really)
{
int i;
int has_errors = 0;
@@ -171,12 +195,19 @@ static int refresh_cache(void)
continue;
}
- new = refresh_entry(ce);
+ new = refresh_entry(ce, really);
if (!new)
continue;
if (IS_ERR(new)) {
if (not_new && PTR_ERR(new) == -ENOENT)
continue;
+ if (really && PTR_ERR(new) == -EINVAL) {
+ /* If we are doing --really-refresh that
+ * means the index is not valid anymore.
+ */
+ ce->ce_flags &= ~htons(CE_VALID);
+ active_cache_changed = 1;
+ }
if (quiet)
continue;
printf("%s: needs update\n", ce->name);
@@ -274,6 +305,8 @@ static int add_cacheinfo(unsigned int mo
memcpy(ce->name, path, len);
ce->ce_flags = create_ce_flags(len, stage);
ce->ce_mode = create_ce_mode(mode);
+ if (assume_unchanged)
+ ce->ce_flags |= htons(CE_VALID);
option = allow_add ? ADD_CACHE_OK_TO_ADD : 0;
option |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0;
if (add_cache_entry(ce, option))
@@ -317,6 +350,12 @@ static void update_one(const char *path,
fprintf(stderr, "Ignoring path %s\n", path);
return;
}
+ if (mark_valid_only) {
+ if (mark_valid(p))
+ die("Unable to mark file %s", path);
+ return;
+ }
+
if (force_remove) {
if (remove_file_from_cache(p))
die("git-update-index: unable to remove %s", path);
@@ -467,7 +506,11 @@ int main(int argc, const char **argv)
continue;
}
if (!strcmp(path, "--refresh")) {
- has_errors |= refresh_cache();
+ has_errors |= refresh_cache(0);
+ continue;
+ }
+ if (!strcmp(path, "--really-refresh")) {
+ has_errors |= refresh_cache(1);
continue;
}
if (!strcmp(path, "--cacheinfo")) {
@@ -493,6 +536,14 @@ int main(int argc, const char **argv)
die("git-update-index: %s cannot chmod %s", path, argv[i]);
continue;
}
+ if (!strcmp(path, "--assume-unchanged")) {
+ mark_valid_only = MARK_VALID;
+ continue;
+ }
+ if (!strcmp(path, "--no-assume-unchanged")) {
+ mark_valid_only = UNMARK_VALID;
+ continue;
+ }
if (!strcmp(path, "--info-only")) {
info_only = 1;
continue;
diff --git a/write-tree.c b/write-tree.c
index f866059..addb5de 100644
--- a/write-tree.c
+++ b/write-tree.c
@@ -111,7 +111,7 @@ int main(int argc, char **argv)
funny = 0;
for (i = 0; i < entries; i++) {
struct cache_entry *ce = active_cache[i];
- if (ntohs(ce->ce_flags) & ~CE_NAMEMASK) {
+ if (ce_stage(ce)) {
if (10 < ++funny) {
fprintf(stderr, "...\n");
break;
--
1.1.6.gbb042
^ permalink raw reply related
* Re: Handling large files with GIT
From: Martin Langhoff @ 2006-02-09 5:38 UTC (permalink / raw)
To: Greg KH; +Cc: Florian Weimer, git
In-Reply-To: <20060209045420.GB15924@kroah.com>
On 2/9/06, Greg KH <greg@kroah.com> wrote:
> Is there anyway to not repack everything if it's not
> need?
I often cg-clone large projects over stupid protocols (http/rsync) and
then hand-edit the branches/origin or remotes/origin file to say
"git://" instead.
It's called cheating but it works great ;-)
m
^ permalink raw reply
* [PATCH] "Assume unchanged" git: do not set CE_VALID with --refresh
From: Junio C Hamano @ 2006-02-09 5:49 UTC (permalink / raw)
To: git
Cc: Alex Riesen, Radoslaw Szkodzinski, Keith Packard, cworth,
Martin Langhoff, Linus Torvalds
In-Reply-To: <7vek2di043.fsf@assigned-by-dhcp.cox.net>
When working with automatic assume-unchanged mode using
core.ignorestat, setting CE_VALID after --refresh makes things
more cumbersome to use. Consider this scenario:
(1) the working tree is on a filesystem with slow lstat(2).
The user sets core.ignorestat = true.
(2) "git checkout" to switch to a different branch (or initial
checkout) updates all paths and the index starts out with
"all clean".
(3) The user knows she wants to edit certain paths. She uses
update-index --no-assume-unchanged (we could call it --edit;
the name is inmaterial) to mark these paths and starts
editing.
(4) After editing half of the paths marked to be edited, she
runs "git status". This runs "update-index --refresh" to
reduce the false hits from diff-files.
(5) Now the other half of the paths, since she has not changed
them, are found to match the index, and CE_VALID is set on
them again.
For this reason, this commit makes update-index --refresh not to
set CE_VALID even after the path without CE_VALID are verified
to be up to date. The user still can run --really-refresh to
force lstat() to match the index entries to the reality.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
update-index.c | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
fd4e57f17733d85ed5346d70005ea900cb80b9ff
diff --git a/update-index.c b/update-index.c
index 767fd49..bb73050 100644
--- a/update-index.c
+++ b/update-index.c
@@ -172,6 +172,15 @@ static struct cache_entry *refresh_entry
memcpy(updated, ce, size);
fill_stat_cache_info(updated, &st);
+ /* In this case, if really is not set, we should leave
+ * CE_VALID bit alone. Otherwise, paths marked with
+ * --no-assume-unchanged (i.e. things to be edited) will
+ * reacquire CE_VALID bit automatically, which is not
+ * really what we want.
+ */
+ if (!really && assume_unchanged && !(ce->ce_flags & htons(CE_VALID)))
+ updated->ce_flags &= ~htons(CE_VALID);
+
return updated;
}
--
1.1.6.gbb042
^ permalink raw reply related
* [PATCH] ls-files: debugging aid for CE_VALID changes.
From: Junio C Hamano @ 2006-02-09 5:50 UTC (permalink / raw)
To: git
Cc: Alex Riesen, Radoslaw Szkodzinski, Keith Packard, cworth,
Martin Langhoff, Linus Torvalds
In-Reply-To: <7vek2di043.fsf@assigned-by-dhcp.cox.net>
This is not really part of the proposed updates for CE_VALID,
but with this change, ls-files -t shows CE_VALID paths with
lowercase tag letters instead of the usual uppercase. Useful
for checking out what is going on.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
ls-files.c | 18 +++++++++++++++++-
1 files changed, 17 insertions(+), 1 deletions(-)
775ca05ee2ba7e1f54ec4db1fed7069014364f2c
diff --git a/ls-files.c b/ls-files.c
index 6af3b09..3f06ece 100644
--- a/ls-files.c
+++ b/ls-files.c
@@ -447,6 +447,22 @@ static void show_ce_entry(const char *ta
if (pathspec && !match(pathspec, ce->name, len))
return;
+ if (tag && *tag && (ce->ce_flags & htons(CE_VALID))) {
+ static char alttag[4];
+ memcpy(alttag, tag, 3);
+ if (isalpha(tag[0]))
+ alttag[0] = tolower(tag[0]);
+ else if (tag[0] == '?')
+ alttag[0] = '!';
+ else {
+ alttag[0] = 'v';
+ alttag[1] = tag[0];
+ alttag[2] = ' ';
+ alttag[3] = 0;
+ }
+ tag = alttag;
+ }
+
if (!show_stage) {
fputs(tag, stdout);
write_name_quoted("", 0, ce->name + offset,
@@ -503,7 +519,7 @@ static void show_files(void)
err = lstat(ce->name, &st);
if (show_deleted && err)
show_ce_entry(tag_removed, ce);
- if (show_modified && ce_modified(ce, &st))
+ if (show_modified && ce_modified(ce, &st, 0))
show_ce_entry(tag_modified, ce);
}
}
--
1.1.6.gbb042
^ permalink raw reply related
* What's in git.git
From: Junio C Hamano @ 2006-02-09 6:47 UTC (permalink / raw)
To: git
I haven't heard major breakage around the new features scheduled
for 1.2.0 so far, except for the two-tree "diff-tree --cc" Linus
has already fixed, so the previous "What's new" is pretty much
unchanged.
One *major* change I am thinking about doing is to change my
workflow a bit. So far, the proposed updates branch "pu" was
almost impossible to follow unless you are really a devoted git
developer, because it is always rebased to the latest master and
then topic branches are merged onto it. While that keeps the
number of unnecessary merge nodes between master and pu to the
minimum, it actively discouraged for the branch to be followed
by developers.
I would like to rectify that.
So I have created another branch, "next". This is managed quite
differently from "pu". I'd promise these things:
* It is to contain planned updates and merge from topic
branches, just like "pu" currently does. However, the topics
merged there will not contain majorly whacky / unproven ones
like bind commits and shallow clones, until the basic part
proves sound during the list discussion.
* I will not rewind or rebase the "next" branch. Also I will
not rebase the topic branches that are merged into it.
* It would occasionally merge from "master" if only to prevent
conflicts.
* If there are patches sent to improve a topic branch in it,
they will be applied to the topic branch, and then the topic
branch is merged into "next", without any funny rewinding or
rebasing of "next". This will make the "next" branch
cluttered with repeated merges from the same topic branch,
but that is OK. "next" will not be merged into "master",
ever.
* Once a topic is fully cooked, the topic branch will be merged
into "master".
What this means is that "next" should be as easy to follow as
"master", but still is slightly ahead of "master" with not so
wildly experimental features.
Although there theoretically is no reason not to follow the
above principles I set for "next" to manage "pu", it will stay
wild for now until I get more comfortable with this workflow.
Now, what's in "next"? Currently I have two topic branches
merged to it.
* jc/nostat:
ls-files: debugging aid for CE_VALID changes.
"Assume unchanged" git: do not set CE_VALID with --refresh
"Assume unchanged" git
* jc/empty-commit:
t6000: fix a careless test library add-on.
Do not allow empty name or email.
^ permalink raw reply
* [PATCH] ls-files: honour per-directory ignore file from higher directories.
From: Junio C Hamano @ 2006-02-09 8:16 UTC (permalink / raw)
To: Pavel Roskin; +Cc: Sam Ravnborg, git
In-Reply-To: <20060125061140.GA8408@mars.ravnborg.org>
When git-ls-files -o --exclude-per-directory=.gitignore is run
from a subdirectory, it did not read from .gitignore from its
parent directory. Reading from them makes output from these two
commands consistent:
$ git ls-files -o --exclude-per-directory=.gitignore Documentation
$ cd Documentation &&
git ls-files -o --exclude-per-directory=.gitignore
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
* If there are positive feedbacks on this one, I consider it
a safe enough candidate to be included in 1.2.0 release.
ls-files.c | 22 +++++++++++++++++++++-
1 files changed, 21 insertions(+), 1 deletions(-)
701ca744e386c2429ca44072ea987bbb4bdac7ce
diff --git a/ls-files.c b/ls-files.c
index 6af3b09..7024cf1 100644
--- a/ls-files.c
+++ b/ls-files.c
@@ -474,8 +474,28 @@ static void show_files(void)
const char *path = ".", *base = "";
int baselen = prefix_len;
- if (baselen)
+ if (baselen) {
path = base = prefix;
+ if (exclude_per_dir) {
+ char *p, *pp = xmalloc(baselen+1);
+ memcpy(pp, prefix, baselen+1);
+ p = pp;
+ while (1) {
+ char save = *p;
+ *p = 0;
+ push_exclude_per_directory(pp, p-pp);
+ *p++ = save;
+ if (!save)
+ break;
+ p = strchr(p, '/');
+ if (p)
+ p++;
+ else
+ p = pp + baselen;
+ }
+ free(pp);
+ }
+ }
read_directory(path, base, baselen);
qsort(dir, nr_dir, sizeof(struct nond_on_fs *), cmp_name);
if (show_others)
--
1.1.6.gbb042
^ permalink raw reply related
* Re: What's in git.git
From: sean @ 2006-02-09 8:09 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vslqtf2p1.fsf@assigned-by-dhcp.cox.net>
On Wed, 08 Feb 2006 22:47:54 -0800
Junio C Hamano <junkio@cox.net> wrote:
> One *major* change I am thinking about doing is to change my
> workflow a bit. So far, the proposed updates branch "pu" was
> almost impossible to follow unless you are really a devoted git
> developer, because it is always rebased to the latest master and
> then topic branches are merged onto it. While that keeps the
> number of unnecessary merge nodes between master and pu to the
> minimum, it actively discouraged for the branch to be followed
> by developers.
I've always followed it okay by just using "git branch -d pu" each time
before pulling from you. Your "next" branch does sound like an
improvement though.
Sean
^ permalink raw reply
* Re: What's in git.git
From: Andreas Ericsson @ 2006-02-09 9:04 UTC (permalink / raw)
To: sean; +Cc: Junio C Hamano, git
In-Reply-To: <BAYC1-PASMTP1142DA49F5BC7B7B42B22FAE030@CEZ.ICE>
sean wrote:
> On Wed, 08 Feb 2006 22:47:54 -0800
> Junio C Hamano <junkio@cox.net> wrote:
>
>
>
>>One *major* change I am thinking about doing is to change my
>>workflow a bit. So far, the proposed updates branch "pu" was
>>almost impossible to follow unless you are really a devoted git
>>developer, because it is always rebased to the latest master and
>>then topic branches are merged onto it. While that keeps the
>>number of unnecessary merge nodes between master and pu to the
>>minimum, it actively discouraged for the branch to be followed
>>by developers.
>
>
> I've always followed it okay by just using "git branch -d pu" each time
> before pulling from you. Your "next" branch does sound like an
> improvement though.
>
I thought
Pull: +pu:pu
was supposed to handle such things automatically. It has always pulled
properly for me anyways.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply
* Re: [PATCH] Add git-annotate - a tool for annotating files with the revision and person that created each line in the file.
From: Andreas Ericsson @ 2006-02-09 9:19 UTC (permalink / raw)
To: git
In-Reply-To: <86ek2dsn5f.fsf@blue.stonehenge.com>
Randal L. Schwartz wrote:
>>>>>>"Franck" == Franck Bui-Huu <vagabon.xyz@gmail.com> writes:
>
>
> Franck> another perl script :(
>
> Franck> Are there any rules on the choice of the script language ?
>
> I could argue that they should all be Perl. :)
>
Brave thing to do among such a bunch of hardcore C hackers. ;)
So long as we never involve ruby, java or DCL, I'm a happy fellow.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply
* Re: What's in git.git
From: sean @ 2006-02-09 9:40 UTC (permalink / raw)
To: Andreas Ericsson; +Cc: junkio, git
In-Reply-To: <43EB05B5.20307@op5.se>
On Thu, 09 Feb 2006 10:04:53 +0100
Andreas Ericsson <ae@op5.se> wrote:
> I thought
>
> Pull: +pu:pu
>
> was supposed to handle such things automatically. It has always pulled
> properly for me anyways.
>
The only problem with that is that Junio rebases and discards commits
periodically that will still be in your local pu branch. The fetch/merge
logic doesn't notice that commits have disappeared from Junio's pu branch.
So you'll end up with a union of all the pu branches in your local repo
with commits that were dropped and never merged into mainline by Junio.
Unless you add changes to the pu branch locally you should never need
anything but a fast forward when pulling from Junio. Except it breaks
when he rebases things. The easy hackish "fix" is just to delete and repull
the branch which is always small anyway.
Sean
^ permalink raw reply
* Re: What's in git.git
From: Junio C Hamano @ 2006-02-09 9:55 UTC (permalink / raw)
To: Andreas Ericsson; +Cc: sean, Ryan Anderson, git
In-Reply-To: <43EB05B5.20307@op5.se>
Andreas Ericsson <ae@op5.se> writes:
> sean wrote:
>> I've always followed it okay by just using "git branch -d pu" each
>> time before pulling from you. Your "next" branch does sound like
>> an improvement though.
>
> I thought
>
> Pull: +pu:pu
>
> was supposed to handle such things automatically. It has always pulled
> properly for me anyways.
Yes, fetching to look at is no problem, but what I wanted to
solve is that you cannot easily _touch_ it. The point of this
is to make improving on top of what is still _not_ in master
easier for the contributors.
If you want to improve upon what is in the current "pu", the
natural thing for you to do would be:
$ git fetch git://git.kernel.org/pub/scm/git/git +pu:pu
$ git checkout -b my-pu pu ;# initial
$ hack on it and git commit many times
$ git format-patch --stdout pu..my-pu |
git send-email --to junkio@cox.net --cc git@vger.kernel.org
(Side note: I do not know git-send-email would work like the
above, but if it did that might be handy. Ryan?)
But sometimes you may take more time than how my "pu"
progresses, and you would want to sync your work to my updated
"pu". A natural thing you would want to do is this:
$ git pull git://git.kernel.org/pub/scm/git/git +pu:pu
Unfortunately, this would _not_ work very well, because by the
time you pull from my "pu" again, it would have rewound and
rebased. You would end up seeing unnecessary merge conflicts.
Another possibility would be:
$ git fetch git://git.kernel.org/pub/scm/git/git +pu:pu
$ git rebase pu
This helps somewhat because "git rebase" uses "git cherry" to
detect the same patch with different commit ID in "pu" that you
already have in "my-pu". But my topic branches have been
sometimes rewound and even rewritten to fix minor points (using
"reset --soft HEAD^" followed by "commit -a -c ORIG_HEAD"), and
when that happens "git rebase" would not be of much help.
The updated workflow on my part is trying to reduce these
problems by (1) not rewinding nor rebasing "next" and (2) not
rewinding nor rebasing the topic branches merged into "next".
Strictly speaking, the latter is not necessary (I would need to
resolve conflicts when merging the rewound/rebased topic
branches into "next", but after that is done, contributors who
pulled "next" do not have to deal with that, as long as "next"
itself is not rewound/rebased), but that way you could disect
component topic branches more easily out of "next".
For example, as of this writhing, my "master" and "next" look
like this:
$ git show-branch --topo-order master next
* [master] .gitignore git-rerere and config.mak
! [next] Merge branch 'jc/nostat'
--
- [next] Merge branch 'jc/nostat'
+ [next^2] "Assume unchanged" git: --really-refresh fix.
- [next^] Merge branch 'jc/ls-files-o'
+ [next^^2] ls-files: honour per-directory ignore file ...
- [next~2] Merge branches 'jc/nostat' and 'jc/empty-commit'
+ [next~2^3] t6000: fix a careless test library add-on.
+ [next~2^3^] Do not allow empty name or email.
+ [next^2^] ls-files: debugging aid for CE_VALID changes.
+ [next^2~2] "Assume unchanged" git: do not set CE_VALID...
+ [next^2~3] "Assume unchanged" git
*+ [master] .gitignore git-rerere and config.mak
If you want to help fixing my thinko in jc/nostat branch, you
could:
$ git checkout -b jc/nostat next^2
$ fix fix fix; git commit
By convention, merge records what was the tip of the branch as
the first parent, and the second parent (and subsequent ones if
it is an Octopus) is the tip of the branch that was merged in,
so you can tell "next^2" is what was merged into the branch to
advance "next"; in other words, that is the tip of the jc/nostat
branch. Similarly, you can tell the tip of jc/empty-commit was
merged to next~2 in an Octopus as the second merged-in branch,
so you can tell that its tip is next~2^3.
You could even publish your jc/nostat branch after you built on
it and tell me to pull from it to fix my stupidity.
^ permalink raw reply
* Re: [PATCH] Add git-annotate - a tool for annotating files with the revision and person that created each line in the file.
From: Junio C Hamano @ 2006-02-09 9:57 UTC (permalink / raw)
To: Andreas Ericsson; +Cc: git
In-Reply-To: <43EB093A.1060207@op5.se>
Andreas Ericsson <ae@op5.se> writes:
> So long as we never involve ruby, java or DCL, I'm a happy fellow.
Wholeheartedly seconded ;-).
^ permalink raw reply
* Re: What's in git.git
From: Johannes Schindelin @ 2006-02-09 9:58 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vslqtf2p1.fsf@assigned-by-dhcp.cox.net>
Hi,
On Wed, 8 Feb 2006, Junio C Hamano wrote:
> So I have created another branch, "next".
I never quite understood why you not just publish your topic branches.
IMHO what you intend to put into "next" should be put into "master"
anyway: everyone interested in git development should try the new features
as early as possible. If there is a "whacky" feature, you can put it into
"whacky/archexport" or something along the lines.
Ciao,
Dscho
^ permalink raw reply
* [PATCH] Fix t9000-init.sh - comment for initial commit is different
From: Pavel Roskin @ 2006-02-09 10:01 UTC (permalink / raw)
To: Petr Baudis, git
[PATCH] Fix t9000-init.sh - comment for initial commit is different
Comment for initial commit has "Initial commit" prepended to it now.
Update test to match.
Signed-off-by: Pavel Roskin <proski@gnu.org>
---
t/t9000-init.sh | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/t/t9000-init.sh b/t/t9000-init.sh
index aef2587..b3b9df3 100755
--- a/t/t9000-init.sh
+++ b/t/t9000-init.sh
@@ -37,7 +37,8 @@ test_expect_success 'initialize with the
test_expect_success 'check if we have a commit' \
'[ -s .git/refs/heads/master ] && cg-object-id -c HEAD'
test_expect_success 'check if the commit is proper' \
- '[ "$(git-cat-file commit HEAD | sed -n '\''/^parent/q; /^$/{n; :a p; n; b a}'\'')" = "silly commit message" ]'
+ '[ "$(git-cat-file commit HEAD | sed -n '\''/^parent/q; /^$/{n; :a p; n; b a}'\'')" = "Initial commit
+silly commit message" ]'
test_expect_success 'check if we have populated index' \
'[ "$(git-ls-files | tr '\''\n'\'' " ")" = "file1 file2 " ]'
test_expect_success 'blow away the repository' \
--
Regards,
Pavel Roskin
^ permalink raw reply related
* Re: What's in git.git
From: Andreas Ericsson @ 2006-02-09 10:29 UTC (permalink / raw)
To: git
In-Reply-To: <7vk6c4etzy.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano wrote:
> Andreas Ericsson <ae@op5.se> writes:
>
>
>>sean wrote:
>>
>>>I've always followed it okay by just using "git branch -d pu" each
>>>time before pulling from you. Your "next" branch does sound like
>>>an improvement though.
>>
>>I thought
>>
>> Pull: +pu:pu
>>
>>was supposed to handle such things automatically. It has always pulled
>>properly for me anyways.
>
>
> Yes, fetching to look at is no problem, but what I wanted to
> solve is that you cannot easily _touch_ it. The point of this
> is to make improving on top of what is still _not_ in master
> easier for the contributors.
>
> If you want to improve upon what is in the current "pu", the
> natural thing for you to do would be:
>
> $ git fetch git://git.kernel.org/pub/scm/git/git +pu:pu
> $ git checkout -b my-pu pu ;# initial
> $ hack on it and git commit many times
> $ git format-patch --stdout pu..my-pu |
> git send-email --to junkio@cox.net --cc git@vger.kernel.org
>
This is exactly what I do when I improve upon things in master, and
according to numerous emails this is the recommended workflow.
> (Side note: I do not know git-send-email would work like the
> above, but if it did that might be handy. Ryan?)
>
With my (still un-published) git-send-patch you could do
$ work, work, work
$ git send-patch -s "Some subject for a prelude message" pu
and it would do the right thing.
I guess I'll have to get around to sending that thing in sooner or later.
> But sometimes you may take more time than how my "pu"
> progresses, and you would want to sync your work to my updated
> "pu". A natural thing you would want to do is this:
>
> $ git pull git://git.kernel.org/pub/scm/git/git +pu:pu
>
Do you mean
$ git pull git://git.kernel.org/pub/scm/git/git +pu:my-pu
? Otherwise, I don't see how I can end up with merge-conflicts.
> Unfortunately, this would _not_ work very well, because by the
> time you pull from my "pu" again, it would have rewound and
> rebased. You would end up seeing unnecessary merge conflicts.
>
> Another possibility would be:
>
> $ git fetch git://git.kernel.org/pub/scm/git/git +pu:pu
> $ git rebase pu
>
Using my own topic-branch, this is what I always do. Conflicts that
occur that way are always in my patches, so they would have to be
reworked anyway. The new rerere tool should help if I dally too long.
Perhaps I'm just weird, but I never touch published branches.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ 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