* [PATCH 2] renaming git add -i [r]evert -> reset and adding gitt add -i [c]heckout
From: Marc Weber @ 2008-10-05 21:46 UTC (permalink / raw)
To: git
In-Reply-To: <20081005164124.GA31903@coredump.intra.peff.net>
Hi Jeff, thanks!
I'll try to do it better now (not sure who is the mantainer though, I've
seen that you've commited some lines to this file)..
Both patches apply cleanly against c427559 (master).
You can push enhancements directly to
git://mawercer.de/git_my_patches
topic branches:
renaming_revert_to_reset
revert_to_reset_renaming
Sincerly
Marc Weber
============= attachement git show output ============================
commit 852b21bf88b1de784244a6e99de9a53a5c61dd8c
Author: Marc Weber <marco-oweber@gmx.de>
Date: Sun Oct 5 23:09:04 2008 +0200
rename the git add -i [r]evert command to [r]eset to use the same term as in git reset
purpose: decrease possibility of confusion for users with svn background (svn revert = git checkout)
Signed-off-by: Marc Weber <marco-oweber@gmx.de>
diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index da768ee..5352d16 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -498,8 +498,8 @@ sub update_cmd {
print "\n";
}
-sub revert_cmd {
- my @update = list_and_choose({ PROMPT => 'Revert',
+sub reset_cmd {
+ my @update = list_and_choose({ PROMPT => 'Reset',
HEADER => $status_head, },
list_modified());
if (@update) {
@@ -527,7 +527,7 @@ sub revert_cmd {
}
}
refresh();
- say_n_paths('reverted', @update);
+ say_n_paths('reset', @update);
}
print "\n";
}
@@ -1046,7 +1046,7 @@ sub help_cmd {
print colored $help_color, <<\EOF ;
status - show paths with changes
update - add working tree state to the staged set of changes
-revert - revert staged set of changes back to the HEAD version
+reset - reset staged set of changes back to the HEAD version
patch - pick hunks and update selectively
diff - view diff between HEAD and index
add untracked - add contents of untracked files to the staged set of changes
@@ -1070,7 +1070,7 @@ sub process_args {
sub main_loop {
my @cmd = ([ 'status', \&status_cmd, ],
[ 'update', \&update_cmd, ],
- [ 'revert', \&revert_cmd, ],
+ [ 'reset', \&reset_cmd, ],
[ 'add untracked', \&add_untracked_cmd, ],
[ 'patch', \&patch_update_cmd, ],
[ 'diff', \&diff_cmd, ],
commit b3d438764a7429e1dfacef8f499a0126076ed2bc
Author: Marc Weber <marco-oweber@gmx.de>
Date: Sun Oct 5 15:15:38 2008 +0000
renamed revert in ga -i to reset, added [c]heckout
diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index da768ee..32c300f 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -498,8 +498,8 @@ sub update_cmd {
print "\n";
}
-sub revert_cmd {
- my @update = list_and_choose({ PROMPT => 'Revert',
+sub reset_cmd {
+ my @update = list_and_choose({ PROMPT => 'Reset',
HEADER => $status_head, },
list_modified());
if (@update) {
@@ -527,7 +527,31 @@ sub revert_cmd {
}
}
refresh();
- say_n_paths('reverted', @update);
+ say_n_paths('reset', @update);
+ }
+ print "\n";
+}
+
+sub checkout_cmd {
+ my @update = list_and_choose({ PROMPT => 'Checkout',
+ HEADER => $status_head, },
+ list_modified());
+ if (@update) {
+ if (is_initial_commit()) {
+ # should never be executed because there can't
be modified files
+ print "error: no revision in repo yet\n";
+ }
+ else {
+ for (@update) {
+ if ($_->{INDEX_ADDDEL} &&
+ $_->{INDEX_ADDDEL} eq 'create') {
+ system(qw(git checkout --),
+ $_->{VALUE});
+ }
+ }
+ }
+ refresh();
+ say_n_paths('checked out', @update);
}
print "\n";
}
@@ -1046,7 +1070,8 @@ sub help_cmd {
print colored $help_color, <<\EOF ;
status - show paths with changes
update - add working tree state to the staged set of changes
-revert - revert staged set of changes back to the HEAD version
+reset - reset staged set of changes back to the HEAD version
+checkout - reset working copy file back to the HEAD version
patch - pick hunks and update selectively
diff - view diff between HEAD and index
add untracked - add contents of untracked files to the staged set of
changes
@@ -1070,7 +1095,8 @@ sub process_args {
sub main_loop {
my @cmd = ([ 'status', \&status_cmd, ],
[ 'update', \&update_cmd, ],
- [ 'revert', \&revert_cmd, ],
+ [ 'reset', \&reset_cmd, ],
+ [ 'checkout', \&checkout_cmd, ],
[ 'add untracked', \&add_untracked_cmd, ],
[ 'patch', \&patch_update_cmd, ],
[ 'diff', \&diff_cmd, ],
^ permalink raw reply related
* Re: [PATCH 0/4] diff text conversion filter
From: Jakub Narebski @ 2008-10-05 22:03 UTC (permalink / raw)
To: git
In-Reply-To: <20081005214114.GA21875@coredump.intra.peff.net>
Jeff King wrote:
> On Tue, Sep 30, 2008 at 12:45:45PM -0400, Jeff King wrote:
>
>> I am about 90% done cleaning it up for preparation (there is a bit of
>> refactoring, and I want to make sure I get that just right). I'll post
>> it in the next day or so.
>
> Sorry, I didn't get a chance to look at this until today. Patch series
> will follow. It is still missing documentation updates and tests, but I
> wanted to get you something to look at (and as I am proposing a new
> meaning for "diff driver", I would be curious to hear the general
> comments).
>
> This is on top of 'next', because it would otherwise conflict with the
> funcname pattern changes there.
Documentation, pretty please?
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply
* Re: [PATCH 2] renaming git add -i [r]evert -> reset and adding gitt add -i [c]heckout
From: Jeff King @ 2008-10-05 22:11 UTC (permalink / raw)
To: Marc Weber; +Cc: git
In-Reply-To: <20081005214644.GB32727@gmx.de>
On Sun, Oct 05, 2008 at 11:46:44PM +0200, Marc Weber wrote:
> I'll try to do it better now (not sure who is the mantainer though,
> I've seen that you've commited some lines to this file)..
The usual git maintainer is Junio Hamano <gitster@pobox.com>.
But he is out of touch for a few weeks, so the interim maintainer is
Shawn Pearce <spearce@spearce.org>.
> ============= attachement git show output ============================
The usual way of mailing patches is a bit different:
- send one patch per email; if multiple patches are meant to be applied
in series, number them [PATCH i/n]. In this case, I think you would
want your patches applied in series (since the second one will
textually depend on the first).
- use "git format-patch" to generate the patches. This generates an
email format that can be applied on the other end by "git am".
- use "git send-email" to send the patches generated by format-patch.
You can also send the patches directly from your mail reader, but you
will want to merge your regular mail headers with those generated by
format-patch (e.g., the Subject line generated by format-patch should
become the subject line of your message).
> commit 852b21bf88b1de784244a6e99de9a53a5c61dd8c
> Author: Marc Weber <marco-oweber@gmx.de>
> Date: Sun Oct 5 23:09:04 2008 +0200
>
> rename the git add -i [r]evert command to [r]eset to use the same term as in git reset
> purpose: decrease possibility of confusion for users with svn background (svn revert = git checkout)
Please follow the usual "subject\n\nbody" convention for commit
messages. And if the patch touches just one subsystem, we usually say
"subsystem: what the patch does." So something like:
add--interactive: rename [r]evert command to [r]eset
followed by a newline, then your explanation.
I think you may want to note on this patch, too, that "revert" is also
confusing for git users. Maybe like:
The term "revert" is used very confusingly here. In git, to "revert"
is to take the changes made by a previous commit and un-apply them,
creating a new commit. The act of changing what is in the index to
match HEAD is called "reset".
Furthermore, incoming svn users will also find this confusing, since
to them, "revert" means to reset the working tree, which corresponds
to "checkout" in git.
> commit b3d438764a7429e1dfacef8f499a0126076ed2bc
> Author: Marc Weber <marco-oweber@gmx.de>
> Date: Sun Oct 5 15:15:38 2008 +0000
>
> renamed revert in ga -i to reset, added [c]heckout
The first patch has been split out, and then this one contains the
changes for both. So I think what you want to do is to rebase this
change on top of the previous one, so that it should then have just the
"checkout" changes, and then write an appropriate commit message for it.
-Peff
^ permalink raw reply
* Re: [ANNOUNCE] cgit 0.8
From: Lars Hjemli @ 2008-10-05 22:22 UTC (permalink / raw)
To: Asheesh Laroia; +Cc: Git Mailing List
In-Reply-To: <alpine.DEB.2.00.0810051346290.27691@alchemy.localdomain>
On Sun, Oct 5, 2008 at 22:49, Asheesh Laroia <git@asheesh.org> wrote:
> On Sun, 5 Oct 2008, Lars Hjemli wrote:
>
>> cgit-0.8, another webinterface for git, is now available.
>>
> I'm curious - is there any interest in the cgit world in providing gitweb
> URL compatibility?
Well, it's a request that's popped up a few times, but no patches so
far. It would probably be a nice feature if it could be done cleanly.
> Either way, thanks a bundle to all who work on cgit! (And is this the
> canonical place to discuss it?)
You're welcome. And yes, I think this is the place (cgit doesn't have
a mailinglist of its own).
--
larsh
^ permalink raw reply
* RE: gitweb improvements
From: Tjernlund @ 2008-10-05 22:25 UTC (permalink / raw)
To: 'Jakub Narebski'; +Cc: 'git'
In-Reply-To: <m34p3rq7og.fsf@localhost.localdomain>
> -----Original Message-----
> From: Jakub Narebski [mailto:jnareb@gmail.com]
> Sent: den 5 oktober 2008 19:22
> To: Tjernlund
> Cc: 'git'
> Subject: Re: gitweb improvements
>
> "Tjernlund" <tjernlund@tjernlund.se> writes:
>
> > When I browse a repo using gitweb, I miss two things:
> > 1) looking at the history for a file or directory I really want
> > to see the tags there too.
>
> Should be easy to do, but would probably wait (and be indirect result)
> of refactoring/unification of log-like views code ('log', 'shortlog',
> 'history', perhaps also 'rss', 'atom', 'search')
>
> I have added it to my gitweb TODO list...
Great! Thanks.
>
> > 2) looking at a merge like:
> > http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-
> 2.6.git;a=commit;h=66120005e65eed8a05b14a36ab448bdec42f0d6b
> > is somewhat confusing. It really doesn't tell you which commits that is
> > included in the merge.
>
> I don't understand you there. First, you have "(merge: 0d0f3ef 9778e9a)"
> in the navbar, so you can easily go to commit view for parents. Second,
> among commit headers you have two "parent", where SHA-1 of a commit is
> hidden link, and there are also 'commit' and 'diff' link for those.
hmm, looks like I overlooked "(merge: 0d0f3ef 9778e9a)" part. However, I can't
find the "ALSA: make the CS4270 driver a new-style I2C driver" from within
this page.
>
> --
> Jakub Narebski
> Poland
> ShadeHawk on #git
^ permalink raw reply
* (unknown),
From: Robin Rosenberg @ 2008-10-05 23:36 UTC (permalink / raw)
To: git; +Cc: spearce
This series decorates the graphical and text (jgit log) history listings
with tags. For the text command it is optional.
Reviewers may want to pay special attention to the changes in the Ref class.
-- robin
^ permalink raw reply
* [EGIT PATCH 6/6] Comment the getId method and hint for copy to actually get an ObjectId
From: Robin Rosenberg @ 2008-10-05 23:36 UTC (permalink / raw)
To: git; +Cc: spearce, Robin Rosenberg
In-Reply-To: <1223249802-9959-6-git-send-email-robin.rosenberg@dewire.com>
Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
.../src/org/spearce/jgit/revwalk/RevObject.java | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevObject.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevObject.java
index 451205c..2209c04 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevObject.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevObject.java
@@ -67,6 +67,7 @@ abstract void parse(RevWalk walk) throws MissingObjectException,
/**
* Get the name of this object.
+ * See {@link #copy()} to really get a copy
*
* @return unique hash of this object.
*/
--
1.6.0.1.310.gf789d0.dirty
^ permalink raw reply related
* [EGIT PATCH 2/6] Peel annotated tags when getting all refs
From: Robin Rosenberg @ 2008-10-05 23:36 UTC (permalink / raw)
To: git; +Cc: spearce, Robin Rosenberg
In-Reply-To: <1223249802-9959-2-git-send-email-robin.rosenberg@dewire.com>
For packed refs we got this automatically from packed-refs,
but for loose tags we have to follow the tags and get the leaf
object in order to comply with the documentation.
Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
.../src/org/spearce/jgit/lib/RefDatabase.java | 24 ++++++++++++++++++-
1 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
index 5a1b85f..1ee70d9 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
@@ -271,7 +271,16 @@ private void readOneLooseRef(final Map<String, Ref> avail,
return;
}
- ref = new Ref(Ref.Storage.LOOSE, origName, refName, id);
+ Object tt = db.mapObject(id, refName);
+ if (tt != null && tt instanceof Tag) {
+ Tag t = (Tag)tt;
+ while (t != null && t.getType().equals(Constants.TYPE_TAG))
+ t = db.mapTag(t.getTag(), t.getObjId());
+ if (t != null)
+ ref = new Ref(Ref.Storage.LOOSE, origName, refName, id, t.getObjId());
+ } else
+ ref = new Ref(Ref.Storage.LOOSE, origName, refName, id);
+
looseRefs.put(ref.getName(), ref);
looseRefsMTime.put(ref.getName(), ent.lastModified());
avail.put(ref.getName(), ref);
@@ -363,7 +372,18 @@ private Ref readRefBasic(final String origName, final String name, final int dep
throw new IOException("Not a ref: " + name + ": " + line);
}
- ref = new Ref(Ref.Storage.LOOSE, origName, name, id);
+ Object tt = db.mapObject(id, origName);
+ if (tt != null && tt instanceof Tag) {
+ Tag t = (Tag)tt;
+ while (t != null && t.getType().equals(Constants.TYPE_TAG))
+ t = db.mapTag(t.getTag(), t.getObjId());
+ if (t != null)
+ ref = new Ref(Ref.Storage.LOOSE, origName, name, id, t.getObjId());
+ } else
+ ref = new Ref(Ref.Storage.LOOSE, origName, name, id);
+
+ looseRefs.put(origName, ref);
+ ref = new Ref(Ref.Storage.LOOSE, origName, id);
looseRefs.put(name, ref);
looseRefsMTime.put(name, mtime);
return ref;
--
1.6.0.1.310.gf789d0.dirty
^ permalink raw reply related
* [EGIT PATCH 3/6] Add a method to get refs by object Id
From: Robin Rosenberg @ 2008-10-05 23:36 UTC (permalink / raw)
To: git; +Cc: spearce, Robin Rosenberg
In-Reply-To: <1223249802-9959-3-git-send-email-robin.rosenberg@dewire.com>
Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
.../src/org/spearce/jgit/lib/Repository.java | 28 ++++++++++++++++++++
1 files changed, 28 insertions(+), 0 deletions(-)
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
index dfce1b8..3fc5236 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
@@ -47,6 +47,7 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
@@ -939,6 +940,33 @@ public String getBranch() throws IOException {
}
/**
+ * @return a map with all objects referenced by a peeled ref.
+ */
+ public Map<AnyObjectId, List<Ref>> getAllRefsByPeeledObjectId() {
+ Map<String, Ref> allRefs = getAllRefs();
+ HashMap<AnyObjectId, List<Ref>> ret = new HashMap<AnyObjectId, List<Ref>>(allRefs.size());
+ for (Map.Entry<String,Ref> e : allRefs.entrySet()) {
+ Ref ref = e.getValue();
+ AnyObjectId target = ref.getPeeledObjectId();
+ if (target == null)
+ target = ref.getObjectId();
+ List<Ref> list = ret.get(target);
+ if (list == null) {
+ list = Collections.singletonList(ref);
+ } else {
+ if (list.size() == 1) {
+ ArrayList<Ref> list2 = new ArrayList<Ref>(2);
+ list2.add(list.get(0));
+ list = list2;
+ }
+ list.add(ref);
+ }
+ ret.put(target, list);
+ }
+ return ret;
+ }
+
+ /**
* @return true if HEAD points to a StGit patch.
*/
public boolean isStGitMode() {
--
1.6.0.1.310.gf789d0.dirty
^ permalink raw reply related
* [EGIT PATCH 5/6] Add decorate option to log program
From: Robin Rosenberg @ 2008-10-05 23:36 UTC (permalink / raw)
To: git; +Cc: spearce, Robin Rosenberg
In-Reply-To: <1223249802-9959-5-git-send-email-robin.rosenberg@dewire.com>
Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
.../src/org/spearce/jgit/pgm/Log.java | 32 ++++++++++++++++++++
1 files changed, 32 insertions(+), 0 deletions(-)
diff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Log.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Log.java
index e16387b..378d9e0 100644
--- a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Log.java
+++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Log.java
@@ -40,10 +40,17 @@
import java.text.DateFormat;
import java.text.SimpleDateFormat;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
import java.util.TimeZone;
+import org.kohsuke.args4j.Option;
+import org.spearce.jgit.lib.AnyObjectId;
import org.spearce.jgit.lib.PersonIdent;
+import org.spearce.jgit.lib.Ref;
import org.spearce.jgit.revwalk.RevCommit;
+import org.spearce.jgit.revwalk.RevWalk;
@Command(common = true, usage = "View commit history")
class Log extends RevWalkTextBuiltin {
@@ -51,14 +58,39 @@
private final DateFormat fmt;
+ private Map<AnyObjectId, List<Ref>> allRefsByPeeledObjectId;
+
+ @Option(name="--decorate", usage="Show ref names matching commits")
+ private boolean decorate;
+
Log() {
fmt = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy ZZZZZ");
}
@Override
+ protected org.spearce.jgit.revwalk.RevWalk createWalk() {
+ RevWalk ret = super.createWalk();
+ if (decorate)
+ allRefsByPeeledObjectId = getRepository().getAllRefsByPeeledObjectId();
+ return ret;
+ }
+
+ @Override
protected void show(final RevCommit c) throws Exception {
out.print("commit ");
c.getId().copyTo(outbuffer, out);
+ if (decorate) {
+ List<Ref> list = allRefsByPeeledObjectId.get(c.copy());
+ if (list != null) {
+ out.print(" (");
+ for (Iterator<Ref> i = list.iterator(); i.hasNext(); ) {
+ out.print(i.next().getOrigName());
+ if (i.hasNext())
+ out.print(" ");
+ }
+ out.print(")");
+ }
+ }
out.println();
final PersonIdent author = c.getAuthorIdent();
--
1.6.0.1.310.gf789d0.dirty
^ permalink raw reply related
* [EGIT PATCH 1/6] Keep original ref name when reading refs
From: Robin Rosenberg @ 2008-10-05 23:36 UTC (permalink / raw)
To: git; +Cc: spearce, Robin Rosenberg
In-Reply-To: <1223249802-9959-1-git-send-email-robin.rosenberg@dewire.com>
We want to know the original name of refs, not just the target name.
Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java | 63 +++++++++++++++++++-
.../src/org/spearce/jgit/lib/RefDatabase.java | 45 +++++++++-----
.../src/org/spearce/jgit/lib/RefUpdate.java | 14 ++---
3 files changed, 94 insertions(+), 28 deletions(-)
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java
index db94875..2f102af 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java
@@ -43,6 +43,11 @@
* A ref in Git is (more or less) a variable that holds a single object
* identifier. The object identifier can be any valid Git object (blob, tree,
* commit, annotated tag, ...).
+ * <p>
+ * The ref name has the attributes of the ref that was asked for as well as
+ * the ref it was resolved to for symbolic refs plus the object id it points
+ * to and (for tags) the peeled target object id, i.e. the tag resolved
+ * recursively until a non-tag object is referenced.
*/
public class Ref {
/** Location where a {@link Ref} is stored. */
@@ -119,19 +124,24 @@ public boolean isPacked() {
private ObjectId peeledObjectId;
+ private final String origName;
+
/**
* Create a new ref pairing.
*
* @param st
* method used to store this ref.
+ * @param origName
+ * The name used to resolve this ref
* @param refName
* name of this ref.
* @param id
* current value of the ref. May be null to indicate a ref that
* does not exist yet.
*/
- public Ref(final Storage st, final String refName, final ObjectId id) {
+ public Ref(final Storage st, final String origName, final String refName, final ObjectId id) {
storage = st;
+ this.origName = origName;
name = refName;
objectId = id;
}
@@ -146,19 +156,56 @@ public Ref(final Storage st, final String refName, final ObjectId id) {
* @param id
* current value of the ref. May be null to indicate a ref that
* does not exist yet.
+ */
+ public Ref(final Storage st, final String refName, final ObjectId id) {
+ this(st, refName, refName, id);
+ }
+
+ /**
+ * Create a new ref pairing.
+ *
+ * @param st
+ * method used to store this ref.
+ * @param origName
+ * The name used to resolve this ref
+ * @param refName
+ * name of this ref.
+ * @param id
+ * current value of the ref. May be null to indicate a ref that
+ * does not exist yet.
* @param peel
* peeled value of the ref's tag. May be null if this is not a
* tag or the peeled value is not known.
*/
- public Ref(final Storage st, final String refName, final ObjectId id,
+ public Ref(final Storage st, final String origName, final String refName, final ObjectId id,
final ObjectId peel) {
storage = st;
+ this.origName = origName;
name = refName;
objectId = id;
peeledObjectId = peel;
}
/**
+ * Create a new ref pairing.
+ *
+ * @param st
+ * method used to store this ref.
+ * @param refName
+ * name of this ref.
+ * @param id
+ * current value of the ref. May be null to indicate a ref that
+ * does not exist yet.
+ * @param peel
+ * peeled value of the ref's tag. May be null if this is not a
+ * tag or the peeled value is not known.
+ */
+ public Ref(final Storage st, final String refName, final ObjectId id,
+ final ObjectId peel) {
+ this(st, refName, refName, id, peel);
+ }
+
+ /**
* What this ref is called within the repository.
*
* @return name of this ref.
@@ -168,6 +215,13 @@ public String getName() {
}
/**
+ * @return the originally resolved name
+ */
+ public String getOrigName() {
+ return origName;
+ }
+
+ /**
* Cached value of this ref.
*
* @return the value of this ref at the last time we read it.
@@ -200,6 +254,9 @@ public Storage getStorage() {
}
public String toString() {
- return "Ref[" + name + "=" + ObjectId.toString(getObjectId()) + "]";
+ String o = "";
+ if (!origName.equals(name))
+ o = "(" + origName + ")";
+ return "Ref[" + o + name + "=" + ObjectId.toString(getObjectId()) + "]";
}
}
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
index 5c1f060..5a1b85f 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
@@ -51,6 +51,7 @@
import java.util.Map;
import org.spearce.jgit.errors.ObjectWritingException;
+import org.spearce.jgit.lib.Ref.Storage;
import org.spearce.jgit.util.FS;
import org.spearce.jgit.util.NB;
@@ -135,8 +136,8 @@ RefUpdate newUpdate(final String name) throws IOException {
return new RefUpdate(this, r, fileForRef(r.getName()));
}
- void stored(final String name, final ObjectId id, final long time) {
- looseRefs.put(name, new Ref(Ref.Storage.LOOSE, name, id));
+ void stored(final String origName, final String name, final ObjectId id, final long time) {
+ looseRefs.put(name, new Ref(Ref.Storage.LOOSE, origName, name, id));
looseRefsMTime.put(name, time);
setModified();
db.fireRefsMaybeChanged();
@@ -222,12 +223,12 @@ private void readLooseRefs(final Map<String, Ref> avail,
final String entName = ent.getName();
if (".".equals(entName) || "..".equals(entName))
continue;
- readOneLooseRef(avail, prefix + entName, ent);
+ readOneLooseRef(avail, prefix + entName, prefix + entName, ent);
}
}
private void readOneLooseRef(final Map<String, Ref> avail,
- final String refName, final File ent) {
+ final String origName, final String refName, final File ent) {
// Unchanged and cached? Don't read it again.
//
Ref ref = looseRefs.get(refName);
@@ -270,7 +271,7 @@ private void readOneLooseRef(final Map<String, Ref> avail,
return;
}
- ref = new Ref(Ref.Storage.LOOSE, refName, id);
+ ref = new Ref(Ref.Storage.LOOSE, origName, refName, id);
looseRefs.put(ref.getName(), ref);
looseRefsMTime.put(ref.getName(), ent.lastModified());
avail.put(ref.getName(), ref);
@@ -293,27 +294,35 @@ private File fileForRef(final String name) {
return new File(gitDir, name);
}
- private Ref readRefBasic(final String name, final int depth)
+ private Ref readRefBasic(final String name, final int depth) throws IOException {
+ return readRefBasic(name, name, depth);
+ }
+
+ private Ref readRefBasic(final String origName, final String name, final int depth)
throws IOException {
// Prefer loose ref to packed ref as the loose
// file can be more up-to-date than a packed one.
//
- Ref ref = looseRefs.get(name);
+ Ref ref = looseRefs.get(origName);
final File loose = fileForRef(name);
final long mtime = loose.lastModified();
if (ref != null) {
Long cachedlastModified = looseRefsMTime.get(name);
if (cachedlastModified != null && cachedlastModified == mtime)
return ref;
- looseRefs.remove(name);
- looseRefsMTime.remove(name);
+ looseRefs.remove(origName);
+ looseRefsMTime.remove(origName);
}
if (mtime == 0) {
// If last modified is 0 the file does not exist.
// Try packed cache.
//
- return packedRefs.get(name);
+ ref = packedRefs.get(name);
+ if (ref != null)
+ if (!ref.getOrigName().equals(origName))
+ ref = new Ref(Storage.LOOSE_PACKED, origName, name, ref.getObjectId());
+ return ref;
}
final String line;
@@ -324,7 +333,7 @@ private Ref readRefBasic(final String name, final int depth)
}
if (line == null || line.length() == 0)
- return new Ref(Ref.Storage.LOOSE, name, null);
+ return new Ref(Ref.Storage.LOOSE, origName, name, null);
if (line.startsWith("ref: ")) {
if (depth >= 5) {
@@ -333,12 +342,16 @@ private Ref readRefBasic(final String name, final int depth)
}
final String target = line.substring("ref: ".length());
- final Ref r = readRefBasic(target, depth + 1);
+ Ref r = readRefBasic(target, target, depth + 1);
Long cachedMtime = looseRefsMTime.get(name);
if (cachedMtime != null && cachedMtime != mtime)
setModified();
looseRefsMTime.put(name, mtime);
- return r != null ? r : new Ref(Ref.Storage.LOOSE, target, null);
+ if (r == null)
+ return new Ref(Ref.Storage.LOOSE, origName, target, null);
+ if (!origName.equals(r.getName()))
+ r = new Ref(Ref.Storage.LOOSE_PACKED, origName, r.getName(), r.getObjectId(), r.getPeeledObjectId());
+ return r;
}
setModified();
@@ -350,7 +363,7 @@ private Ref readRefBasic(final String name, final int depth)
throw new IOException("Not a ref: " + name + ": " + line);
}
- ref = new Ref(Ref.Storage.LOOSE, name, id);
+ ref = new Ref(Ref.Storage.LOOSE, origName, name, id);
looseRefs.put(name, ref);
looseRefsMTime.put(name, mtime);
return ref;
@@ -384,7 +397,7 @@ private void refreshPackedRefs() {
final ObjectId id = ObjectId.fromString(p.substring(1));
last = new Ref(Ref.Storage.PACKED, last.getName(), last
- .getObjectId(), id);
+ .getName(), last.getObjectId(), id);
newPackedRefs.put(last.getName(), last);
continue;
}
@@ -392,7 +405,7 @@ private void refreshPackedRefs() {
final int sp = p.indexOf(' ');
final ObjectId id = ObjectId.fromString(p.substring(0, sp));
final String name = new String(p.substring(sp + 1));
- last = new Ref(Ref.Storage.PACKED, name, id);
+ last = new Ref(Ref.Storage.PACKED, name, name, id);
newPackedRefs.put(last.getName(), last);
}
} finally {
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
index 86b44c5..235c2fd 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
@@ -131,9 +131,6 @@
/** Repository the ref is stored in. */
private final RefDatabase db;
- /** Name of the ref. */
- private final String name;
-
/** Location of the loose file holding the value of this ref. */
private final File looseFile;
@@ -160,7 +157,6 @@
RefUpdate(final RefDatabase r, final Ref ref, final File f) {
db = r;
this.ref = ref;
- name = ref.getName();
oldValue = ref.getObjectId();
looseFile = f;
}
@@ -171,7 +167,7 @@ RefUpdate(final RefDatabase r, final Ref ref, final File f) {
* @return name of this ref.
*/
public String getName() {
- return name;
+ return ref.getName();
}
/**
@@ -349,9 +345,9 @@ public Result delete() throws IOException {
* @throws IOException
*/
public Result delete(final RevWalk walk) throws IOException {
- if (name.startsWith(Constants.R_HEADS)) {
+ if (getName().startsWith(Constants.R_HEADS)) {
final Ref head = db.readRef(Constants.HEAD);
- if (head != null && name.equals(head.getName()))
+ if (head != null && getName().equals(head.getName()))
return Result.REJECTED_CURRENT_BRANCH;
}
@@ -373,7 +369,7 @@ private Result updateImpl(final RevWalk walk, final Store store)
if (!lock.lock())
return Result.LOCK_FAILURE;
try {
- oldValue = db.idOf(name);
+ oldValue = db.idOf(getName());
if (oldValue == null)
return store.store(lock, Result.NEW);
@@ -428,7 +424,7 @@ else if (status == Result.NEW)
getName());
if (!lock.commit())
return Result.LOCK_FAILURE;
- db.stored(name, newValue, lock.getCommitLastModified());
+ db.stored(this.ref.getOrigName(), ref.getName(), newValue, lock.getCommitLastModified());
return status;
}
--
1.6.0.1.310.gf789d0.dirty
^ permalink raw reply related
* [EGIT PATCH 4/6] Add tags to the graphical history display.
From: Robin Rosenberg @ 2008-10-05 23:36 UTC (permalink / raw)
To: git; +Cc: spearce, Robin Rosenberg
In-Reply-To: <1223249802-9959-4-git-send-email-robin.rosenberg@dewire.com>
Both the SWT (Eclipse) drawing and Swing versions are updated.
The coloring and shapes are intentionally not the same as for gitk.
Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
.../egit/core/internal/storage/KidWalk.java | 3 +-
.../egit/ui/internal/history/SWTCommit.java | 5 +-
.../egit/ui/internal/history/SWTPlotRenderer.java | 64 +++++++++++++++++++-
.../spearce/egit/ui/internal/history/SWTWalk.java | 5 +-
.../org/spearce/jgit/awtui/AWTPlotRenderer.java | 46 ++++++++++++++
.../spearce/jgit/revplot/AbstractPlotRenderer.java | 18 +++++-
.../src/org/spearce/jgit/revplot/PlotCommit.java | 8 ++-
.../src/org/spearce/jgit/revplot/PlotWalk.java | 56 ++++++++++++++++-
.../src/org/spearce/jgit/revwalk/RevWalk.java | 19 +++++-
9 files changed, 209 insertions(+), 15 deletions(-)
diff --git a/org.spearce.egit.core/src/org/spearce/egit/core/internal/storage/KidWalk.java b/org.spearce.egit.core/src/org/spearce/egit/core/internal/storage/KidWalk.java
index 6b8f468..b337efe 100644
--- a/org.spearce.egit.core/src/org/spearce/egit/core/internal/storage/KidWalk.java
+++ b/org.spearce.egit.core/src/org/spearce/egit/core/internal/storage/KidWalk.java
@@ -11,6 +11,7 @@
import org.spearce.jgit.lib.AnyObjectId;
import org.spearce.jgit.lib.Repository;
import org.spearce.jgit.revwalk.RevCommit;
+import org.spearce.jgit.lib.Ref;
import org.spearce.jgit.revwalk.RevWalk;
class KidWalk extends RevWalk {
@@ -19,7 +20,7 @@ KidWalk(final Repository repo) {
}
@Override
- protected RevCommit createCommit(final AnyObjectId id) {
+ protected RevCommit createCommit(final AnyObjectId id, final Ref[] tags) {
return new KidCommit(id);
}
}
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTCommit.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTCommit.java
index fa0d25d..2341fbd 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTCommit.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTCommit.java
@@ -10,12 +10,13 @@
import org.eclipse.swt.widgets.Widget;
import org.spearce.jgit.lib.AnyObjectId;
import org.spearce.jgit.revplot.PlotCommit;
+import org.spearce.jgit.lib.Ref;
class SWTCommit extends PlotCommit<SWTCommitList.SWTLane> {
Widget widget;
- SWTCommit(final AnyObjectId id) {
- super(id);
+ SWTCommit(final AnyObjectId id, final Ref[] tags) {
+ super(id, tags);
}
@Override
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTPlotRenderer.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTPlotRenderer.java
index 23ec255..56d5842 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTPlotRenderer.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTPlotRenderer.java
@@ -15,7 +15,10 @@
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.ui.themes.ColorUtil;
import org.spearce.egit.ui.internal.history.SWTCommitList.SWTLane;
+import org.spearce.jgit.lib.Constants;
+import org.spearce.jgit.lib.Ref;
import org.spearce.jgit.revplot.AbstractPlotRenderer;
import org.spearce.jgit.revplot.PlotCommit;
@@ -26,7 +29,13 @@
private final Color sys_gray;
- private Color sys_darkblue;
+ private final Color sys_darkblue;
+
+ private final Color sys_yellow;
+
+ private final Color sys_green;
+
+ private final Color sys_white;
GC g;
@@ -43,6 +52,9 @@ SWTPlotRenderer(final Display d) {
sys_black = d.getSystemColor(SWT.COLOR_BLACK);
sys_gray = d.getSystemColor(SWT.COLOR_GRAY);
sys_darkblue = d.getSystemColor(SWT.COLOR_DARK_BLUE);
+ sys_yellow = d.getSystemColor(SWT.COLOR_YELLOW);
+ sys_green = d.getSystemColor(SWT.COLOR_GREEN);
+ sys_white = d.getSystemColor(SWT.COLOR_WHITE);
}
void paint(final Event event) {
@@ -92,7 +104,57 @@ protected void drawText(final String msg, final int x, final int y) {
g.drawString(msg, cellX + x, cellY + texty);
}
+ @Override
+ protected int drawLabel(int x, int y, Ref ref) {
+ String txt;
+ String name = ref.getOrigName();
+ if (name.startsWith(Constants.R_HEADS)) {
+ g.setBackground(sys_green);
+ txt = name.substring(Constants.R_HEADS.length());
+ } else if (name.startsWith(Constants.R_REMOTES)){
+ g.setBackground(sys_gray);
+ txt = name.substring(Constants.R_REMOTES.length());
+ } else if (name.startsWith(Constants.R_TAGS)){
+ g.setBackground(sys_yellow);
+ txt = name.substring(Constants.R_TAGS.length());
+ } else {
+ // Whatever this would be
+ g.setBackground(sys_white);
+ if (name.startsWith(Constants.R_REFS))
+ txt = name.substring(Constants.R_REFS.length());
+ else
+ txt = name; // HEAD and such
+ }
+ Color peeledColor = null;
+ if (ref.getPeeledObjectId() != null) {
+ peeledColor = new Color(g.getDevice(), ColorUtil.blend(g.getBackground().getRGB(), sys_white.getRGB()));
+ g.setBackground(peeledColor);
+ }
+ if (txt.length() > 12)
+ txt = txt.substring(0,11) + "\u2026"; // ellipsis "â¦" (in UTF-8)
+
+ Point testsz = g.stringExtent(txt);
+ final int texty = (y * 2 - testsz.y) / 2;
+ g.setForeground(sys_black);
+ g.drawString(txt, x + 2, cellY + texty);
+ g.setLineWidth(2);
+ Color blend1 = new Color(g.getDevice(), ColorUtil.blend(g.getBackground().getRGB(), sys_gray.getRGB()));
+ g.setForeground(blend1);
+ g.drawRoundRectangle(x, cellY + texty -2, testsz.x + 3, testsz.y + 3, testsz.y/4, testsz.y/4);
+ g.setLineWidth(2);
+ Color blend2 = new Color(g.getDevice(), ColorUtil.blend(g.getBackground().getRGB(), sys_black.getRGB()));
+ g.setForeground(blend2);
+ g.drawRoundRectangle(x + 1, cellY + texty -1, testsz.x + 1, testsz.y + 1, testsz.y/4, testsz.y/4);
+
+ blend1.dispose();
+ blend2.dispose();
+ if (peeledColor != null)
+ peeledColor.dispose();
+ return 8 + testsz.x;
+ }
+
protected Color laneColor(final SWTLane myLane) {
return myLane != null ? myLane.color : sys_black;
}
+
}
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTWalk.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTWalk.java
index 527d284..bc347db 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTWalk.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTWalk.java
@@ -11,6 +11,7 @@
import org.spearce.jgit.lib.Repository;
import org.spearce.jgit.revplot.PlotWalk;
import org.spearce.jgit.revwalk.RevCommit;
+import org.spearce.jgit.lib.Ref;
class SWTWalk extends PlotWalk {
SWTWalk(final Repository repo) {
@@ -18,7 +19,7 @@ SWTWalk(final Repository repo) {
}
@Override
- protected RevCommit createCommit(final AnyObjectId id) {
- return new SWTCommit(id);
+ protected RevCommit createCommit(final AnyObjectId id, final Ref[] tags) {
+ return new SWTCommit(id, tags);
}
}
diff --git a/org.spearce.jgit/src/org/spearce/jgit/awtui/AWTPlotRenderer.java b/org.spearce.jgit/src/org/spearce/jgit/awtui/AWTPlotRenderer.java
index b6b715c..5dcddf5 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/awtui/AWTPlotRenderer.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/awtui/AWTPlotRenderer.java
@@ -44,6 +44,8 @@
import org.spearce.jgit.awtui.CommitGraphPane.GraphCellRender;
import org.spearce.jgit.awtui.SwingCommitList.SwingLane;
+import org.spearce.jgit.lib.Constants;
+import org.spearce.jgit.lib.Ref;
import org.spearce.jgit.revplot.AbstractPlotRenderer;
import org.spearce.jgit.revplot.PlotCommit;
@@ -134,4 +136,48 @@ void paintTriangleDown(final int cx, final int y, final int h) {
g.drawPolygon(triangle);
}
+ @Override
+ protected int drawLabel(int x, int y, Ref ref) {
+ String txt;
+ String name = ref.getOrigName();
+ if (name.startsWith(Constants.R_HEADS)) {
+ g.setBackground(Color.GREEN);
+ txt = name.substring(Constants.R_HEADS.length());
+ } else if (name.startsWith(Constants.R_REMOTES)){
+ g.setBackground(Color.LIGHT_GRAY);
+ txt = name.substring(Constants.R_REMOTES.length());
+ } else if (name.startsWith(Constants.R_TAGS)){
+ g.setBackground(Color.YELLOW);
+ txt = name.substring(Constants.R_TAGS.length());
+ } else {
+ // Whatever this would be
+ g.setBackground(Color.WHITE);
+ if (name.startsWith(Constants.R_REFS))
+ txt = name.substring(Constants.R_REFS.length());
+ else
+ txt = name; // HEAD and such
+ }
+ if (ref.getPeeledObjectId() != null) {
+ float[] colorComponents = g.getBackground().getRGBColorComponents(null);
+ colorComponents[0] *= 0.9;
+ colorComponents[1] *= 0.9;
+ colorComponents[2] *= 0.9;
+ g.setBackground(new Color(colorComponents[0],colorComponents[1],colorComponents[2]));
+ }
+ if (txt.length() > 12)
+ txt = txt.substring(0,11) + "\u2026"; // ellipsis "â¦" (in UTF-8)
+
+ final int texth = g.getFontMetrics().getHeight();
+ int textw = g.getFontMetrics().stringWidth(txt);
+ g.setColor(g.getBackground());
+ int arcHeight = texth/4;
+ int y0 = y - texth/2 + (cell.getHeight() - texth)/2;
+ g.fillRoundRect(x , y0, textw + arcHeight*2, texth -1, arcHeight, arcHeight);
+ g.setColor(g.getColor().darker());
+ g.drawRoundRect(x, y0, textw + arcHeight*2, texth -1 , arcHeight, arcHeight);
+ g.setColor(Color.BLACK);
+ g.drawString(txt, x + arcHeight, y0 + texth - g.getFontMetrics().getDescent());
+
+ return arcHeight * 3 + textw;
+ }
}
\ No newline at end of file
diff --git a/org.spearce.jgit/src/org/spearce/jgit/revplot/AbstractPlotRenderer.java b/org.spearce.jgit/src/org/spearce/jgit/revplot/AbstractPlotRenderer.java
index f175c9d..603547b 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/revplot/AbstractPlotRenderer.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/revplot/AbstractPlotRenderer.java
@@ -37,6 +37,7 @@
package org.spearce.jgit.revplot;
+import org.spearce.jgit.lib.Ref;
import org.spearce.jgit.revwalk.RevFlag;
/**
@@ -140,11 +141,24 @@ protected void paintCommit(final PlotCommit<TLane> commit, final int h) {
else
drawCommitDot(dotX, dotY, dotSize, dotSize);
+ int textx = Math.max(maxCenter + LANE_WIDTH / 2, dotX + dotSize) + 8;
+ int n = commit.refs == null ? 0 : commit.refs.length;
+ for (int i = 0; i < n; ++i) {
+ textx += drawLabel(textx + dotSize, h/2, commit.refs[i]);
+ }
+
final String msg = commit.getShortMessage();
- final int textx = Math.max(maxCenter + LANE_WIDTH / 2, dotX + dotSize) + 8;
- drawText(msg, textx, h / 2);
+ drawText(msg, textx + dotSize + n*2, h / 2);
}
+ /** FIXME: supply text
+ * @param x
+ * @param y
+ * @param ref TODO
+ * @return TODO
+ */
+ protected abstract int drawLabel(int x, int y, Ref ref);
+
private int computeDotSize(final int h) {
int d = (int) (Math.min(h, LANE_WIDTH) * 0.50f);
d += (d & 1);
diff --git a/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotCommit.java b/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotCommit.java
index 5a5ef1e..fac89f5 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotCommit.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotCommit.java
@@ -39,6 +39,7 @@
import org.spearce.jgit.lib.AnyObjectId;
import org.spearce.jgit.revwalk.RevCommit;
+import org.spearce.jgit.lib.Ref;
/**
* A commit reference to a commit in the DAG.
@@ -58,14 +59,19 @@
PlotCommit[] children;
+ Ref[] refs;
+
/**
* Create a new commit.
*
* @param id
* the identity of this commit.
+ * @param tags
+ * the tags associated with this commit, null for no tags
*/
- protected PlotCommit(final AnyObjectId id) {
+ protected PlotCommit(final AnyObjectId id, final Ref[] tags) {
super(id);
+ this.refs = tags;
passingLanes = NO_LANES;
children = NO_CHILDREN;
}
diff --git a/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotWalk.java b/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotWalk.java
index e5e8aba..6e253f4 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotWalk.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotWalk.java
@@ -37,14 +37,26 @@
package org.spearce.jgit.revplot;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
import org.spearce.jgit.lib.AnyObjectId;
+import org.spearce.jgit.lib.Commit;
+import org.spearce.jgit.lib.Ref;
import org.spearce.jgit.lib.Repository;
+import org.spearce.jgit.lib.Tag;
import org.spearce.jgit.revwalk.RevCommit;
import org.spearce.jgit.revwalk.RevSort;
import org.spearce.jgit.revwalk.RevWalk;
/** Specialized RevWalk for visualization of a commit graph. */
public class PlotWalk extends RevWalk {
+
+ Map<AnyObjectId, List<Ref>> reverseRefMap;
+
/**
* Create a new revision walker for a given repository.
*
@@ -54,6 +66,7 @@
public PlotWalk(final Repository repo) {
super(repo);
super.sort(RevSort.TOPO, true);
+ reverseRefMap = repo.getAllRefsByPeeledObjectId();
}
@Override
@@ -64,7 +77,46 @@ public void sort(final RevSort s, final boolean use) {
}
@Override
- protected RevCommit createCommit(final AnyObjectId id) {
- return new PlotCommit(id);
+ protected RevCommit createCommit(final AnyObjectId id, final Ref[] tags) {
+ return new PlotCommit(id, tags);
+ }
+
+ @Override
+ protected Ref[] getTags(final AnyObjectId commitId) {
+ List<Ref> list = reverseRefMap.get(commitId);
+ Ref[] tags;
+ if (list == null)
+ tags = null;
+ else {
+ if (list != null && list.size() > 1) {
+ Collections.sort(list, new Comparator<Ref>() {
+ public int compare(Ref o1, Ref o2) {
+ try {
+ Object obj1 = getRepository().mapObject(o1.getObjectId(), o1.getName());
+ Object obj2 = getRepository().mapObject(o2.getObjectId(), o2.getName());
+ long t1 = timeof(obj1);
+ long t2 = timeof(obj2);
+ if (t1 > t2)
+ return -1;
+ if (t1 < t2)
+ return 1;
+ return 0;
+ } catch (IOException e) {
+ // ignore
+ return 0;
+ }
+ }
+ long timeof(Object o) {
+ if (o instanceof Commit)
+ return ((Commit)o).getCommitter().getWhen().getTime();
+ if (o instanceof Tag)
+ return ((Tag)o).getTagger().getWhen().getTime();
+ return 0;
+ }
+ });
+ }
+ tags = list.toArray(new Ref[list.size()]);
+ }
+ return tags;
}
}
diff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevWalk.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevWalk.java
index d7e4c58..41d57c6 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevWalk.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevWalk.java
@@ -53,6 +53,7 @@
import org.spearce.jgit.lib.ObjectId;
import org.spearce.jgit.lib.ObjectIdSubclassMap;
import org.spearce.jgit.lib.ObjectLoader;
+import org.spearce.jgit.lib.Ref;
import org.spearce.jgit.lib.Repository;
import org.spearce.jgit.lib.WindowCursor;
import org.spearce.jgit.revwalk.filter.RevFilter;
@@ -541,7 +542,7 @@ public RevTree lookupTree(final AnyObjectId id) {
public RevCommit lookupCommit(final AnyObjectId id) {
RevCommit c = (RevCommit) objects.get(id);
if (c == null) {
- c = createCommit(id);
+ c = createCommit(id, getTags(id));
objects.add(c);
}
return c;
@@ -564,7 +565,7 @@ public RevObject lookupAny(final AnyObjectId id, final int type) {
if (r == null) {
switch (type) {
case Constants.OBJ_COMMIT:
- r = createCommit(id);
+ r = createCommit(id, getTags(id));
break;
case Constants.OBJ_TREE:
r = new RevTree(id);
@@ -687,7 +688,7 @@ public RevObject parseAny(final AnyObjectId id)
final int type = ldr.getType();
switch (type) {
case Constants.OBJ_COMMIT: {
- final RevCommit c = createCommit(ldr.getId());
+ final RevCommit c = createCommit(ldr.getId(), getTags(ldr.getId()));
c.parseCanonical(this, data);
r = c;
break;
@@ -718,6 +719,14 @@ public RevObject parseAny(final AnyObjectId id)
}
/**
+ * @param commitId
+ * @return the list of refs associated with a commit, possibly filtered
+ */
+ protected Ref[] getTags(final AnyObjectId commitId) {
+ return null; // Don't get tags in the basic case
+ }
+
+ /**
* Ensure the object's content has been parsed.
* <p>
* This method only returns successfully if the object exists and was parsed
@@ -1008,9 +1017,11 @@ private boolean isNotStarted() {
*
* @param id
* the object this walker requires a commit reference for.
+ * @param tags
+ * tags attached to the commit
* @return a new unparsed reference for the object.
*/
- protected RevCommit createCommit(final AnyObjectId id) {
+ protected RevCommit createCommit(final AnyObjectId id, final Ref[] tags) {
return new RevCommit(id);
}
--
1.6.0.1.310.gf789d0.dirty
^ permalink raw reply related
* Re: gitweb improvements
From: Jakub Narebski @ 2008-10-05 23:54 UTC (permalink / raw)
To: Tjernlund; +Cc: 'git'
In-Reply-To: <00b201c92739$36585eb0$a3091c10$@se>
On Mon, 6 Oct 2008, Tjernlund wrote:
> Jakub Narebski wrote:
>> "Tjernlund" <tjernlund@tjernlund.se> writes:
>>> 2) looking at a merge like:
>>> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=66120005e65eed8a05b14a36ab448bdec42f0d6b
>>> is somewhat confusing. It really doesn't tell you which commits that is
>>> included in the merge.
>>
>> I don't understand you there. First, you have "(merge: 0d0f3ef 9778e9a)"
>> in the navbar, so you can easily go to commit view for parents. Second,
>> among commit headers you have two "parent", where SHA-1 of a commit is
>> hidden link, and there are also 'commit' and 'diff' link for those.
>
> hmm, looks like I overlooked "(merge: 0d0f3ef 9778e9a)" part. However, I can't
> find the "ALSA: make the CS4270 driver a new-style I2C driver" from within
> this page.
I think you don't quite understand the situation. The history looks
like this:
M Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
|\
| 2 ALSA: ASoC: Fix another cs4270 error path
| * ALSA: make the CS4270 driver a new-style I2C driver
| |
1 | Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6
Parents of commit 'M' (for merge) are '1' and '2', not 2,* or 1,2,*.
Now the fact that commit message for merge contains shortlog of merged
branch does not mean that there must be direct link to such shortlog.
You can go to shortlog (well, kind of) if you click on second parent,
_then_ click on shortlog link at top of the page.
--
Jakub Narebski
Poland
^ permalink raw reply
* Re: [PATCHv4] gitweb: generate parent..current URLs
From: Jakub Narebski @ 2008-10-06 0:17 UTC (permalink / raw)
To: Giuseppe Bilotta; +Cc: git, Petr Baudis, Junio C Hamano, Shawn O. Pearce
In-Reply-To: <1222906234-8182-7-git-send-email-giuseppe.bilotta@gmail.com>
On Thu, 2 Oct 2008, Giuseppe Bilotta wrote:
> If use_pathinfo is enabled, href now creates links that contain paths in
> the form $project/$action/oldhash:/oldname..newhash:/newname for actions
> that use hash_parent etc.
[cut]
>From the first glance, it looks good. I just worry a bit about
complicated issue of hash_parent vs hash_parent_base etc.
--
Jakub Narebski
Poland
^ permalink raw reply
* git UI feature matrix (was: Re: teamGit v0.0.3)
From: Stephan Beyer @ 2008-10-06 1:33 UTC (permalink / raw)
To: bain; +Cc: git
In-Reply-To: <22717858-31ce-4979-9d8e-167601f0e82e@i24g2000prf.googlegroups.com>
Hi,
bain wrote:
> > Could you please add info about teamGit to the git wiki page
> > http://git.or.cz/gitwiki/InterfacesFrontendsAndTools? I think
> > just below now defunct and unmaintained KGit (or just above) would
> > be best.
> Will do ASAP
Because there are a lot of UIs and GUIs for git I thought a "feature
matrix" could be cool. I created a stub on the mentioned wiki page.
So it'd be nice if you could add a column for teamGit there and perhaps
some rows for features that are worth mentioning (if those already exist
in teamGit).
I was unsure what features are useful to mention, because I do not really
use git GUIs. (I only use gitk for history viewing, but only when I'm
too lazy to type "git log --decorate --graph".)
Regards,
Stephan
PS: Such a feature matrix could also be useful for the git web
interfaces.
--
Stephan Beyer <s-beyer@gmx.net>, PGP 0x6EDDD207FCC5040F
^ permalink raw reply
* Re: git UI feature matrix (was: Re: teamGit v0.0.3)
From: Martin Langhoff @ 2008-10-06 1:52 UTC (permalink / raw)
To: Stephan Beyer; +Cc: bain, git
In-Reply-To: <20081006013303.GB25639@leksak.fem-net>
On Mon, Oct 6, 2008 at 2:33 PM, Stephan Beyer <s-beyer@gmx.net> wrote:
> Hi,
>
> bain wrote:
>> > Could you please add info about teamGit to the git wiki page
>> > http://git.or.cz/gitwiki/InterfacesFrontendsAndTools? I think
>> > just below now defunct and unmaintained KGit (or just above) would
>> > be best.
>> Will do ASAP
>
> Because there are a lot of UIs and GUIs for git I thought a "feature
> matrix" could be cool. I created a stub on the mentioned wiki page.
I volunteer to start a "give a beer to a programmer that eschews
writing his own and helps others polish/extend an existing one" fund
:-p
cheers,
m
--
martin.langhoff@gmail.com
martin@laptop.org -- School Server Architect
- ask interesting questions
- don't get distracted with shiny stuff - working code first
- http://wiki.laptop.org/go/User:Martinlanghoff
^ permalink raw reply
* Re: git svn: Bad URL passed to RA layer: Unrecognized URL scheme
From: Jeff Kowalczyk @ 2008-10-06 2:28 UTC (permalink / raw)
To: git
In-Reply-To: <237967ef0810051244m51156925x26ae51db038dad49@mail.gmail.com>
Mikael Magnusson wrote:
> That somehow looks more like an svn error than a git error, does
> svn checkout http://code.djangoproject.com/svn work?
You were correct, I tried subversion and got the same error. I rebuilt
(gentoo ~x86) neon-0.28.3, subversion-1.5.2 and git-1.6.0.2, and have
functional git svn operations.
However, each operation ends with a segmentation fault. This is the case
with all git svn repositories (e.g. several different svn remote hosts).
(master) $ git svn rebase
M django/core/management/commands/makemessages.py
M docs/topics/i18n.txt
r9155 = 4c86e60f62366ac9c3fd9369c17c54801a8f2ea0 (trunk)
First, rewinding head to replay your work on top of it...
Fast-forwarded master to refs/remotes/trunk.
Segmentation fault
Does the segfault risk corruption of the git repository data?
Would I report this as a git bug or distribution bug?
Thanks.
^ permalink raw reply
* [PATCH v3] rebase--interactive: fix parent rewriting for dropped commits
From: Stephen Haberman @ 2008-10-06 4:26 UTC (permalink / raw)
To: git; +Cc: ae, spearce
In-Reply-To: <20081003133246.bae6b657.stephen@exigencecorp.com>
`rebase -i -p` got its rev-list of commits to keep by --left-right and
--cherry-pick. Adding --cherry-pick would drop commits that duplicated changes
already in the rebase target.
The dropped commits were then forgotten about when it came to rewriting the
parents of their descendents, so the descendents would get cherry-picked with
their old, unwritten parents and essentially make the rebase a no-op.
This commit adds a $DOTEST/dropped directory to remember dropped commits and
rewrite their children's parent as the dropped commit's possibly-rewritten
first-parent.
Signed-off-by: Stephen Haberman <stephen@exigencecorp.com>
---
These two lines changed from the v2 patch:
pend=" $(cat "$DROPPED"/$p)$pend"
It now puts $p at the start of $pend instead of the end. I have no tests
that assert this behavior (vs. the old of putting it at the end), but it
seems rational to put the dropped-replacement parent first so that the
current commit's parents come out in the same order (otherwise a commit
with parents "p1 p2dropped p3" would end up "p1 p3 p2firstparent").
Also, this line changed:
new_parents="$new_parents $p"
Previously it said "$new_parents $new_p" which was a copy/paste bug--$new_p
was from up in the code a bit and here we just want to use $p.
I also cleaned up the commit message.
git-rebase--interactive.sh | 37 +++++++-
t/t3410-rebase-preserve-dropped-merges.sh | 140 +++++++++++++++++++++++++++++
2 files changed, 175 insertions(+), 2 deletions(-)
create mode 100644 t/t3410-rebase-preserve-dropped-merges.sh
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index edb6ec6..4d53347 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -37,6 +37,7 @@ DONE="$DOTEST"/done
MSG="$DOTEST"/message
SQUASH_MSG="$DOTEST"/message-squash
REWRITTEN="$DOTEST"/rewritten
+DROPPED="$DOTEST"/dropped
PRESERVE_MERGES=
STRATEGY=
ONTO=
@@ -169,8 +170,12 @@ pick_one_preserving_merges () {
# rewrite parents; if none were rewritten, we can fast-forward.
new_parents=
- for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -f2-)
+ pend=" $(git rev-list --parents -1 $sha1 | cut -d' ' -f2-)"
+ while [ "$pend" != "" ]
do
+ p=$(expr "$pend" : ' \([^ ]*\)')
+ pend="${pend# $p}"
+
if test -f "$REWRITTEN"/$p
then
new_p=$(cat "$REWRITTEN"/$p)
@@ -183,7 +188,13 @@ pick_one_preserving_merges () {
;;
esac
else
- new_parents="$new_parents $p"
+ if test -f "$DROPPED"/$p
+ then
+ fast_forward=f
+ pend=" $(cat "$DROPPED"/$p)$pend"
+ else
+ new_parents="$new_parents $p"
+ fi
fi
done
case $fast_forward in
@@ -582,6 +593,28 @@ first and then run 'git rebase --continue' again."
#
EOF
+ # Watch for commits that been dropped by --cherry-pick
+ if test t = "$PRESERVE_MERGES"
+ then
+ mkdir "$DROPPED"
+ # drop the --cherry-pick parameter this time
+ git rev-list $MERGES_OPTION --abbrev-commit \
+ --abbrev=7 $UPSTREAM...$HEAD --left-right | \
+ sed -n "s/^>//p" | while read rev
+ do
+ grep --quiet "$rev" "$TODO"
+ if [ $? -ne 0 ]
+ then
+ # Use -f2 because if rev-list is telling this commit is not
+ # worthwhile, we don't want to track its multiple heads,
+ # just the history of its first-parent for others that will
+ # be rebasing on top of us
+ full=$(git rev-parse $rev)
+ git rev-list --parents -1 $rev | cut -d' ' -f2 > "$DROPPED"/$full
+ fi
+ done
+ fi
+
has_action "$TODO" ||
die_abort "Nothing to do"
diff --git a/t/t3410-rebase-preserve-dropped-merges.sh b/t/t3410-rebase-preserve-dropped-merges.sh
new file mode 100644
index 0000000..7c8862b
--- /dev/null
+++ b/t/t3410-rebase-preserve-dropped-merges.sh
@@ -0,0 +1,140 @@
+#!/bin/sh
+#
+# Copyright (c) 2008 Stephen Haberman
+#
+
+test_description='git rebase preserve merges
+
+This test runs git rebase with preserve merges and ensures commits
+dropped by the --cherry-pick flag have their childrens parents
+rewritten.
+'
+. ./test-lib.sh
+
+# set up two branches like this:
+#
+# A - B - C - D - E
+# \
+# F - G - H
+# \
+# I
+#
+# where B, D and G touch the same file.
+
+test_expect_success 'setup' '
+ : > file1 &&
+ git add file1 &&
+ test_tick &&
+ git commit -m A &&
+ git tag A &&
+ echo 1 > file1 &&
+ test_tick &&
+ git commit -m B file1 &&
+ : > file2 &&
+ git add file2 &&
+ test_tick &&
+ git commit -m C &&
+ echo 2 > file1 &&
+ test_tick &&
+ git commit -m D file1 &&
+ : > file3 &&
+ git add file3 &&
+ test_tick &&
+ git commit -m E &&
+ git tag E &&
+ git checkout -b branch1 A &&
+ : > file4 &&
+ git add file4 &&
+ test_tick &&
+ git commit -m F &&
+ git tag F &&
+ echo 3 > file1 &&
+ test_tick &&
+ git commit -m G file1 &&
+ git tag G &&
+ : > file5 &&
+ git add file5 &&
+ test_tick &&
+ git commit -m H &&
+ git tag H &&
+ git checkout -b branch2 F &&
+ : > file6 &&
+ git add file6 &&
+ test_tick &&
+ git commit -m I &&
+ git tag I
+'
+
+# A - B - C - D - E
+# \ \ \
+# F - G - H -- L \ --> L
+# \ | \
+# I -- G2 -- J -- K I -- K
+# G2 = same changes as G
+test_expect_success 'skip same-resolution merges with -p' '
+ git checkout branch1 &&
+ ! git merge E &&
+ echo 23 > file1 &&
+ git add file1 &&
+ git commit -m L &&
+ git checkout branch2 &&
+ echo 3 > file1 &&
+ git commit -a -m G2 &&
+ ! git merge E &&
+ echo 23 > file1 &&
+ git add file1 &&
+ git commit -m J &&
+ echo file7 > file7 &&
+ git add file7 &&
+ git commit -m K &&
+ GIT_EDITOR=: git rebase -i -p branch1 &&
+ test $(git rev-parse branch2^^) = $(git rev-parse branch1) &&
+ test "23" = "$(cat file1)" &&
+ test "" = "$(cat file6)" &&
+ test "file7" = "$(cat file7)" &&
+
+ git checkout branch1 &&
+ git reset --hard H &&
+ git checkout branch2 &&
+ git reset --hard I
+'
+
+# A - B - C - D - E
+# \ \ \
+# F - G - H -- L \ --> L
+# \ | \
+# I -- G2 -- J -- K I -- G2 -- K
+# G2 = different changes as G
+test_expect_success 'keep different-resolution merges with -p' '
+ git checkout branch1 &&
+ ! git merge E &&
+ echo 23 > file1 &&
+ git add file1 &&
+ git commit -m L &&
+ git checkout branch2 &&
+ echo 4 > file1 &&
+ git commit -a -m G2 &&
+ ! git merge E &&
+ echo 24 > file1 &&
+ git add file1 &&
+ git commit -m J &&
+ echo file7 > file7 &&
+ git add file7 &&
+ git commit -m K &&
+ ! GIT_EDITOR=: git rebase -i -p branch1 &&
+ echo 234 > file1 &&
+ git add file1 &&
+ GIT_EDITOR=: git rebase --continue &&
+ test $(git rev-parse branch2^^^) = $(git rev-parse branch1) &&
+ test "234" = "$(cat file1)" &&
+ test "" = "$(cat file6)" &&
+ test "file7" = "$(cat file7)" &&
+
+ git checkout branch1 &&
+ git reset --hard H &&
+ git checkout branch2 &&
+ git reset --hard I
+'
+
+test_done
+
--
1.6.0.2
^ permalink raw reply related
* Git and tagging hook
From: Kristis Makris @ 2008-10-06 4:45 UTC (permalink / raw)
To: git-u79uwXL29TY76Z2rM5mHXA; +Cc: scmbug-users-G8y9j4K4DsPiwOUmbS1EgQ
[-- Attachment #1.1: Type: text/plain, Size: 366 bytes --]
Hello,
It seems that Git (at least v1.5.6) does not offer hooks on tag creation
(a pre-tag and a post-tag hook). I need such a hook for integrating tag
activities with an issue-tracker. Is it possible to add this hook ?
I had asked about this in the past, but did not receive a response.
http://bugzilla.mkgnu.net/show_bug.cgi?id=991
Thanks,
Kristis
[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
[-- Attachment #2: Type: text/plain, Size: 188 bytes --]
_______________________________________________
scmbug-users mailing list
scmbug-users-G8y9j4K4DsPiwOUmbS1EgQ@public.gmane.org
http://lists.mkgnu.net/cgi-bin/mailman/listinfo/scmbug-users
^ permalink raw reply
* [PATCH] Teach rebase -i to honor pre-rebase hook
From: Nanako Shiraishi @ 2008-10-06 5:14 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: git
In-Reply-To: <20081005222654.6117@nanako3.lavabit.com>
The original git-rebase honored pre-rebase hook so that public branches
can be protected from getting rebased, but rebase --interactive ignored
the hook entirely. This fixes it.
Signed-off-by: Nanako Shiraishi <nanako3@lavabit.com>
---
git-rebase--interactive.sh | 11 ++++
git-rebase.sh | 18 ++++---
t/t3409-rebase-hook.sh | 126 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 148 insertions(+), 7 deletions(-)
create mode 100755 t/t3409-rebase-hook.sh
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index edb6ec6..3350f90 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -65,6 +65,16 @@ output () {
esac
}
+run_pre_rebase_hook () {
+ if test -x "$GIT_DIR/hooks/pre-rebase"
+ then
+ "$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || {
+ echo >&2 "The pre-rebase hook refused to rebase."
+ exit 1
+ }
+ fi
+}
+
require_clean_work_tree () {
# test if working tree is dirty
git rev-parse --verify HEAD > /dev/null &&
@@ -507,6 +517,7 @@ first and then run 'git rebase --continue' again."
;;
--)
shift
+ run_pre_rebase_hook ${1+"$@"}
test $# -eq 1 -o $# -eq 2 || usage
test -d "$DOTEST" &&
die "Interactive rebase already started"
diff --git a/git-rebase.sh b/git-rebase.sh
index 528b604..a30d40c 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -144,6 +144,16 @@ is_interactive () {
done && test -n "$1"
}
+run_pre_rebase_hook () {
+ if test -x "$GIT_DIR/hooks/pre-rebase"
+ then
+ "$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || {
+ echo >&2 "The pre-rebase hook refused to rebase."
+ exit 1
+ }
+ fi
+}
+
test -f "$GIT_DIR"/rebase-apply/applying &&
die 'It looks like git-am is in progress. Cannot rebase.'
@@ -320,13 +330,7 @@ onto_name=${newbase-"$upstream_name"}
onto=$(git rev-parse --verify "${onto_name}^0") || exit
# If a hook exists, give it a chance to interrupt
-if test -x "$GIT_DIR/hooks/pre-rebase"
-then
- "$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || {
- echo >&2 "The pre-rebase hook refused to rebase."
- exit 1
- }
-fi
+run_pre_rebase_hook ${1+"$@"}
# If the branch to rebase is given, that is the branch we will rebase
# $branch_name -- branch being rebased, or HEAD (already detached)
diff --git a/t/t3409-rebase-hook.sh b/t/t3409-rebase-hook.sh
new file mode 100755
index 0000000..bc93dda
--- /dev/null
+++ b/t/t3409-rebase-hook.sh
@@ -0,0 +1,126 @@
+#!/bin/sh
+
+test_description='git rebase with its hook(s)'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ echo hello >file &&
+ git add file &&
+ test_tick &&
+ git commit -m initial &&
+ echo goodbye >file &&
+ git add file &&
+ test_tick &&
+ git commit -m second &&
+ git checkout -b side HEAD^ &&
+ echo world >git &&
+ git add git &&
+ test_tick &&
+ git commit -m side &&
+ git checkout master &&
+ git log --pretty=oneline --abbrev-commit --graph --all &&
+ git branch test side
+'
+
+test_expect_success 'rebase' '
+ git checkout test &&
+ git reset --hard side &&
+ git rebase master &&
+ test "z$(cat git)" = zworld
+'
+
+test_expect_success 'rebase -i' '
+ git checkout test &&
+ git reset --hard side &&
+ EDITOR=true git rebase -i master &&
+ test "z$(cat git)" = zworld
+'
+
+test_expect_success 'setup pre-rebase hook' '
+ mkdir -p .git/hooks &&
+ cat >.git/hooks/pre-rebase <<EOF &&
+#!$SHELL_PATH
+echo "\$1,\$2" >.git/PRE-REBASE-INPUT
+EOF
+ chmod +x .git/hooks/pre-rebase
+'
+
+test_expect_success 'pre-rebase hook gets correct input (1)' '
+ git checkout test &&
+ git reset --hard side &&
+ git rebase master &&
+ test "z$(cat git)" = zworld &&
+ test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,
+
+'
+
+test_expect_success 'pre-rebase hook gets correct input (2)' '
+ git checkout test &&
+ git reset --hard side &&
+ git rebase master test &&
+ test "z$(cat git)" = zworld &&
+ test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,test
+'
+
+test_expect_success 'pre-rebase hook gets correct input (3)' '
+ git checkout test &&
+ git reset --hard side &&
+ git checkout master &&
+ git rebase master test &&
+ test "z$(cat git)" = zworld &&
+ test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,test
+'
+
+test_expect_success 'pre-rebase hook gets correct input (4)' '
+ git checkout test &&
+ git reset --hard side &&
+ EDITOR=true git rebase -i master &&
+ test "z$(cat git)" = zworld &&
+ test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,
+
+'
+
+test_expect_success 'pre-rebase hook gets correct input (5)' '
+ git checkout test &&
+ git reset --hard side &&
+ EDITOR=true git rebase -i master test &&
+ test "z$(cat git)" = zworld &&
+ test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,test
+'
+
+test_expect_success 'pre-rebase hook gets correct input (6)' '
+ git checkout test &&
+ git reset --hard side &&
+ git checkout master &&
+ EDITOR=true git rebase -i master test &&
+ test "z$(cat git)" = zworld &&
+ test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,test
+'
+
+test_expect_success 'setup pre-rebase hook that fails' '
+ mkdir -p .git/hooks &&
+ cat >.git/hooks/pre-rebase <<EOF &&
+#!$SHELL_PATH
+false
+EOF
+ chmod +x .git/hooks/pre-rebase
+'
+
+test_expect_success 'pre-rebase hook stops rebase (1)' '
+ git checkout test &&
+ git reset --hard side &&
+ test_must_fail git rebase master &&
+ test "z$(git symbolic-ref HEAD)" = zrefs/heads/test &&
+ test 0 = $(git rev-list HEAD...side | wc -l)
+'
+
+test_expect_success 'pre-rebase hook stops rebase (2)' '
+ git checkout test &&
+ git reset --hard side &&
+ EDITOR=true test_must_fail git rebase -i master &&
+ test "z$(git symbolic-ref HEAD)" = zrefs/heads/test &&
+ test 0 = $(git rev-list HEAD...side | wc -l)
+'
+
+test_done
--
1.6.0.2
--
Nanako Shiraishi
http://ivory.ap.teacup.com/nanako3/
^ permalink raw reply related
* [PATCH] rebase --no-verify
From: Nanako Shiraishi @ 2008-10-06 5:14 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: git
In-Reply-To: <20081005222654.6117@nanako3.lavabit.com>
It is sometimes desirable to disable the safety net of pre-rebase hook
when the user knows what he is doing (for example, when the original
changes on the branch have not been shown to the public yet).
This teaches --no-verify option to git-rebase, which is similar to the way
pre-commit hook is bypassed by git-commit.
Signed-off-by: Nanako Shiraishi <nanako3@lavabit.com>
---
It probably is better to fix "rebase -i" to share more code with the main
"rebase" script to avoid duplicated run-pre-rebase-hook function, but it
is beyond what I can do right now. Perhaps people more smart and
beautiful than me can help (^_^;)
git-rebase--interactive.sh | 10 +++++++++-
git-rebase.sh | 7 ++++++-
t/t3409-rebase-hook.sh | 16 ++++++++++++++++
3 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 3350f90..b0d757d 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -26,6 +26,7 @@ i,interactive always used (no-op)
continue continue rebasing process
abort abort rebasing process and restore original branch
skip skip current patch and continue rebasing process
+no-verify override pre-rebase hook from stopping the operation
"
. git-sh-setup
@@ -41,6 +42,7 @@ PRESERVE_MERGES=
STRATEGY=
ONTO=
VERBOSE=
+OK_TO_SKIP_PRE_REBASE=
GIT_CHERRY_PICK_HELP=" After resolving the conflicts,
mark the corrected paths with 'git add <paths>', and
@@ -66,7 +68,8 @@ output () {
}
run_pre_rebase_hook () {
- if test -x "$GIT_DIR/hooks/pre-rebase"
+ if test -z "$OK_TO_SKIP_PRE_REBASE" &&
+ test -x "$GIT_DIR/hooks/pre-rebase"
then
"$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || {
echo >&2 "The pre-rebase hook refused to rebase."
@@ -416,6 +419,11 @@ get_saved_options () {
while test $# != 0
do
case "$1" in
+ --no-verify)
+ OK_TO_SKIP_PRE_REBASE=yes
+ ;;
+ --verify)
+ ;;
--continue)
is_standalone "$@" || usage
get_saved_options
diff --git a/git-rebase.sh b/git-rebase.sh
index a30d40c..f2742aa 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -34,6 +34,7 @@ set_reflog_action rebase
require_work_tree
cd_to_toplevel
+OK_TO_SKIP_PRE_REBASE=
RESOLVEMSG="
When you have resolved this problem run \"git rebase --continue\".
If you would prefer to skip this patch, instead run \"git rebase --skip\".
@@ -145,7 +146,8 @@ is_interactive () {
}
run_pre_rebase_hook () {
- if test -x "$GIT_DIR/hooks/pre-rebase"
+ if test -z "$OK_TO_SKIP_PRE_REBASE" &&
+ test -x "$GIT_DIR/hooks/pre-rebase"
then
"$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || {
echo >&2 "The pre-rebase hook refused to rebase."
@@ -170,6 +172,9 @@ fi
while test $# != 0
do
case "$1" in
+ --no-verify)
+ OK_TO_SKIP_PRE_REBASE=yes
+ ;;
--continue)
test -d "$dotest" -o -d "$GIT_DIR"/rebase-apply ||
die "No rebase in progress?"
diff --git a/t/t3409-rebase-hook.sh b/t/t3409-rebase-hook.sh
index bc93dda..1f1b850 100755
--- a/t/t3409-rebase-hook.sh
+++ b/t/t3409-rebase-hook.sh
@@ -123,4 +123,20 @@ test_expect_success 'pre-rebase hook stops rebase (2)' '
test 0 = $(git rev-list HEAD...side | wc -l)
'
+test_expect_success 'rebase --no-verify overrides pre-rebase (1)' '
+ git checkout test &&
+ git reset --hard side &&
+ git rebase --no-verify master &&
+ test "z$(git symbolic-ref HEAD)" = zrefs/heads/test &&
+ test "z$(cat git)" = zworld
+'
+
+test_expect_success 'rebase --no-verify overrides pre-rebase (2)' '
+ git checkout test &&
+ git reset --hard side &&
+ EDITOR=true git rebase --no-verify -i master &&
+ test "z$(git symbolic-ref HEAD)" = zrefs/heads/test &&
+ test "z$(cat git)" = zworld
+'
+
test_done
--
1.6.0.2
--
Nanako Shiraishi
http://ivory.ap.teacup.com/nanako3/
^ permalink raw reply related
* Re: [PATCH 0/4] diff text conversion filter
From: Johannes Sixt @ 2008-10-06 6:29 UTC (permalink / raw)
To: Jeff King; +Cc: Matthieu Moy, git
In-Reply-To: <20081005214114.GA21875@coredump.intra.peff.net>
Jeff King schrieb:
> On Tue, Sep 30, 2008 at 12:45:45PM -0400, Jeff King wrote:
>
>> I am about 90% done cleaning it up for preparation (there is a bit of
>> refactoring, and I want to make sure I get that just right). I'll post
>> it in the next day or so.
>
> Sorry, I didn't get a chance to look at this until today. Patch series
> will follow. It is still missing documentation updates and tests, but I
> wanted to get you something to look at (and as I am proposing a new
> meaning for "diff driver", I would be curious to hear the general
> comments).
>
> This is on top of 'next', because it would otherwise conflict with the
> funcname pattern changes there.
Does the series in any way change whether plumbing and porcelain invoke
the external diff drivers? I have this particular use-case, which I'd like
that still works:
- In .git/info/attributes I have specified a diff driver:
*.doc diff=docdiff
The driver runs a script that literally loads the two version of the
file into MS Word and uses Word's diffing capability.
- git-gui should not use the diff driver. That is, plumbing should bypass
the diff driver and say "Binary files differ". [*]
- Running 'git diff foo.doc', i.e. porcelain, from a command line should
use the diff driver.
[*] I would not mind seeing a simplified textual diff in git-gui.
-- Hannes
^ permalink raw reply
* Re: [PATCH 0/4] diff text conversion filter
From: Jeff King @ 2008-10-06 6:52 UTC (permalink / raw)
To: Johannes Sixt; +Cc: Matthieu Moy, git
In-Reply-To: <48E9B036.6090805@viscovery.net>
On Mon, Oct 06, 2008 at 08:29:10AM +0200, Johannes Sixt wrote:
> Does the series in any way change whether plumbing and porcelain invoke
> the external diff drivers? I have this particular use-case, which I'd like
> that still works:
No, it tries to keep the behavior the same as it is now (in 2/4, note
how the diff driver config reading is split into porcelain and plumbing
sections). Let me know if you have a test case that doesn't work, or
that you would like me to try.
-Peff
^ permalink raw reply
* Re: Files with colons under Cygwin
From: Johannes Sixt @ 2008-10-06 6:54 UTC (permalink / raw)
To: Dmitry Potapov; +Cc: Giovanni Funchal, git, Shawn O. Pearce
In-Reply-To: <20081004233945.GM21650@dpotapov.dyndns.org>
Dmitry Potapov schrieb:
> Subject: [PATCH] correct verify_path for Windows
>
> Colon and backslash in names may be used on Windows to overwrite files
> outside of the working directory.
>
> Signed-off-by: Dmitry Potapov <dpotapov@gmail.com>
> ---
> read-cache.c | 10 ++++++++++
> 1 files changed, 10 insertions(+), 0 deletions(-)
>
> diff --git a/read-cache.c b/read-cache.c
> index 901064b..972592e 100644
> --- a/read-cache.c
> +++ b/read-cache.c
> @@ -701,6 +701,16 @@ inside:
> }
> return 0;
> }
> +#if defined(_WIN32) || defined(__CYGWIN__)
> + /*
> + * There is a bunch of other characters that are not allowed
> + * in Win32 API, but the following two create a security hole
> + * by allowing to overwrite files outside of the working tree,
> + * therefore they are explicitly prohibited.
> + */
> + else if (c == ':' || c == '\\')
> + return 0;
> +#endif
> c = *path++;
> }
> }
IIUC, verify_path() checks paths that were found in the database or the
index. As such, it checks for the integrity of the database. And paths
with backslashes or colons certainly do not violate the database integrity.
More precisely, the exchange of path names between the index and tree
objects (both directions) should not do this new check, nor if a path is
added to the index. The check is only meaningful[*] when a path is read
from the index or a tree object and "applied" to the working directory.
Unfortunately, I think there are lots of places where this happens.
[*] I say "meaningful" and not "necessary" because the situation is just
like when you grab some random SoftwarePackage.tar.gz, and run ./configure
without looking first what it is going to do.
-- Hannes
^ permalink raw reply
* Re: Build bug report: 'make check' needs sparse, but configure doesn't check it
From: Shawn O. Pearce @ 2008-10-06 6:58 UTC (permalink / raw)
To: Ed Avis; +Cc: git
In-Reply-To: <loom.20081005T094301-345@post.gmane.org>
Ed Avis <eda@waniasset.com> wrote:
> Dmitry Potapov <dpotapov <at> gmail.com> writes:
>
> >The whole point of 'make check' is to run 'sparce' on all files.
>
> >If you want to build
> >and to test the resulting binaries then you run 'make test'.
>
> To reduce confusion I suggest renaming the target to 'make sparse'. Then it's
> obvious what it does and it can't get confused with the more common usage of
> 'make check'.
Nah. We're not going to rename the target to "make sparse".
First off that sounds like we are compiling the sparse binary for
the user, and we will never do that. And existing developers who
use "make check" to run sparse are used to that calling convention.
--
Shawn.
^ 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