* Welcome 2009!
From: Karen @ 2008-09-02 10:09 UTC (permalink / raw)
To: git
Karen created an electronic greeting card.
You can pick it up by clicking on the link below:
http://youryearcard.com/?ID=c3ad319a89d40b03c9
The greeting card will be stored for you for 14 days.
^ permalink raw reply
* Re: [PATCH] Git.pm: let a false Directory parameter (such as 0) be used correctly by the constructor
From: Philippe Bruhat (BooK) @ 2009-01-02 9:09 UTC (permalink / raw)
To: Philippe Bruhat (BooK); +Cc: git, gitster
In-Reply-To: <1230886057-23994-1-git-send-email-book@cpan.org>
On Fri, Jan 02, 2009 at 09:47:37AM +0100, Philippe Bruhat (BooK) wrote:
> Signed-off-by: Philippe Bruhat (BooK) <book@cpan.org>
> ---
> perl/Git.pm | 7 ++++---
> 1 files changed, 4 insertions(+), 3 deletions(-)
Please ignore, I forgot half of the the requested changes. Sorry for the
noise.
--
Philippe Bruhat (BooK)
Mankind is the story of the same mistakes in different places.
(Moral from Groo #1 (Image))
^ permalink raw reply
* [PATCH] Git.pm: let a false Directory parameter be used correctly by the constructor
From: Philippe Bruhat (BooK) @ 2009-01-02 8:49 UTC (permalink / raw)
To: git; +Cc: gitster, Philippe Bruhat (BooK)
The repository constructor mistakenly rewrote a Directory parameter that
Perl happens to evaluate to false (e.g. "0") to ".".
Signed-off-by: Philippe Bruhat (BooK) <book@cpan.org>
---
perl/Git.pm | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/perl/Git.pm b/perl/Git.pm
index 8392a68..ad0f530 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -166,11 +166,12 @@ sub repository {
}
}
- if (not defined $opts{Repository} and not defined $opts{WorkingCopy}) {
- $opts{Directory} ||= '.';
+ if (not defined $opts{Repository} and not defined $opts{WorkingCopy}
+ and not defined $opts{Directory}) {
+ $opts{Directory} = '.';
}
- if ($opts{Directory}) {
+ if (defined $opts{Directory}) {
-d $opts{Directory} or throw Error::Simple("Directory not found: $!");
my $search = Git->repository(WorkingCopy => $opts{Directory});
--
1.6.0.3.517.g759a
^ permalink raw reply related
* [PATCH] Git.pm: let a false Directory parameter (such as 0) be used correctly by the constructor
From: Philippe Bruhat (BooK) @ 2009-01-02 8:47 UTC (permalink / raw)
To: git; +Cc: gitster, Philippe Bruhat (BooK)
Signed-off-by: Philippe Bruhat (BooK) <book@cpan.org>
---
perl/Git.pm | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/perl/Git.pm b/perl/Git.pm
index 8392a68..ad0f530 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -166,11 +166,12 @@ sub repository {
}
}
- if (not defined $opts{Repository} and not defined $opts{WorkingCopy}) {
- $opts{Directory} ||= '.';
+ if (not defined $opts{Repository} and not defined $opts{WorkingCopy}
+ and not defined $opts{Directory}) {
+ $opts{Directory} = '.';
}
- if ($opts{Directory}) {
+ if (defined $opts{Directory}) {
-d $opts{Directory} or throw Error::Simple("Directory not found: $!");
my $search = Git->repository(WorkingCopy => $opts{Directory});
--
1.6.0.3.517.g759a
^ permalink raw reply related
* Re: [PATCH] Git.pm: let a "false" Directory parameter (such as "0") be used correctly by the constructor"
From: Philippe Bruhat (BooK) @ 2009-01-02 8:37 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vwsdeivx9.fsf@gitster.siamese.dyndns.org>
On Thu, Jan 01, 2009 at 01:00:18PM -0800, Junio C Hamano wrote:
> "Philippe Bruhat (BooK)" <book@cpan.org> writes:
>
> > ---
> > perl/Git.pm | 7 ++++---
> > 1 files changed, 4 insertions(+), 3 deletions(-)
>
> Lacks sign-off and description but otherwise looks good. Will queue to
> 'pu' to leave you a chance to re-send.
Yeah, I noticed the lack of Sign-off right after sending. I'll re-send.
--
Philippe Bruhat (BooK)
A reputation is only as good as the truth beneath it, if any.
(Moral from Groo The Wanderer #91 (Epic))
^ permalink raw reply
* Re: [PATCH] Documentation/git-bundle.txt: Dumping contents of any bundle
From: Jeff King @ 2009-01-02 8:27 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: jidanni, johannes.schindelin, nico, gitster, mdl123, git
In-Reply-To: <20090102071519.GA14472@spearce.org>
On Thu, Jan 01, 2009 at 11:15:19PM -0800, Shawn O. Pearce wrote:
> > OK, I wish you luck in the fruition of the new --dump-delta option, and
> > can proofread the man pages involved, otherwise this is no area for
> > junior programmer me.
>
> This is rather insane. There's very little data inside of a delta.
> That's sort of the point of that level of compression, it takes
> up very little disk space and yet describes the change made.
> Almost nobody is going to want the delta without the base object
> it applies onto. No user of git is going to need that. I'd rather
> not carry dead code around in the tree for something nobody will
> ever use.
I somewhat agree. Obviously we can come up with contrived cases where
the delta is a pure "add" and this option magically lets you recover
some text via "strings" on the resulting delta dump. But in practice,
it's hard to say exactly how useful it would be, especially since the
"motivation" here seems to be more academic than any actual real-world
problem. We can approximate with something like:
git clone git://git.kernel.org/pub/scm/git/git.git
cd git
git bundle create ../bundle.git v1.6.0..v1.6.1
mkdir ../broken && cd ../broken
sed '/^PACK/,$!d' ../bundle.git >pack
git init
git unpack-objects --dump-deltas <pack
strings .git/lost-found/delta/* | less
where maybe you lost your actual repository, but you still have a backup
of a bundle you sneaker-netted between major versions. In this instance
we have 6000 objects in the bundle, 2681 of which are blobs (and
therefore presumably the most interesting things to recover). Of those,
1070 were non-delta and can be recovered completely. For the remainder,
our strings command shows us snippets of what was there. There are
definitely recognizable pieces of code. But likewise there are pieces of
code that are missing subtle parts. E.g.:
if (textconv_one) {
size_t size;
mf1.ptr = run_textconv(textconv_one, one, &size);
if (!mf1.
ptr)
mf1.size = size;
if (textconv_two) {
size_t size;
mf2.ptr = run_textconv(textconv_two, two, &size);
if (!mf2.
ptr)
mf2.size = size;
So while there is _something_ to be recovered there, it is basically as
easy to rewrite the code as it is to piece together whatever fragments
are available into something comprehensible.
So in practice, the delta dump would only be useful if:
1. You have an incomplete thin pack, which generally means you are
using bundles (or you interrupted a fetch and kept the tmp_pack).
2. There is _no_ other copy of the basis. The results you get from
this method are so awful that it should really only be last-ditch.
I think you would be insane to say "Oh, I don't have net access
right now. Let me just spend hours picking through these deltas to
find a scrap of something useful instead of just waiting until I
get access again."
3. The changes in the pack tend to produce deltas rather than full
blobs, but the deltas tend to be very add-heavy.
I don't know how popular bundles are, but I would expect (1) puts us
very much in the minority. On top of that, given the nature of git, I
find (2) to be pretty unlikely. If you're sneaker-netting data with a
bundle, then it seems rare that both ends of the net will be lost at
once. As for (3), it seems source code is not a good candidate here.
Perhaps if you were writing a novel in a single file, you might salvage
whole paragraphs or even chapters.
So I am inclined to leave it as-is: a patch in the list archive. If and
when the day comes when somebody loses some super-important data and
somehow matches all of these criteria, then they can consult whatever
aged and senile git gurus still exist to pull the patch out and see if
anything can be recovered.
-Peff
^ permalink raw reply
* Re: [PATCH] http-push: support full URI in handle_remote_ls_ctx()
From: Junio C Hamano @ 2009-01-02 7:26 UTC (permalink / raw)
To: Kirill A. Korinskiy; +Cc: git
In-Reply-To: <1230879195-8567-1-git-send-email-catap@catap.ru>
"Kirill A. Korinskiy" <catap@catap.ru> writes:
> @@ -1424,9 +1425,19 @@ static void handle_remote_ls_ctx(struct xml_ctx *ctx, int tag_closed)
> ls->userFunc(ls);
> }
> } else if (!strcmp(ctx->name, DAV_PROPFIND_NAME) && ctx->cdata) {
> - ls->dentry_name = xmalloc(strlen(ctx->cdata) -
> + char *path = ctx->cdata;
> + if (*ctx->cdata == 'h') {
> + path = strstr(path, "://");
> + if (path) {
> + path = strchr(path+3, '/');
> + }
> + }
Is this "://" (and +3) the only change from the previous one that has
already been queued? I didn't have a problem with the old "//" one.
The check to see if it begins with 'h' bothers me much much more.
If you want to be defensively tight, you should be checking if it begins
with either "http://" or "https://", the only two protocols you are
prepared to handle, and nothing else, so that you won't trigger this
codepath when the other end gave you "hqrt://..", on the basis that your
code won't know if hqrt:// protocol works the same way as http and https.
On the other hand, if you want to be optimistically loose, expecting
whatever people would implement that can be handled with the existing DAV
code would behave the same way as http and https, you shouldn't be
limiting yourself to an unknown protocol name that happens to begin with
an 'h', only accepting "hqrt://" but not "ittp://" URLs.
Your "first byte of the protocol name must be 'h'" does not do either.
^ permalink raw reply
* Re: [PATCH] Documentation/git-bundle.txt: Dumping contents of any bundle
From: Shawn O. Pearce @ 2009-01-02 7:15 UTC (permalink / raw)
To: jidanni; +Cc: peff, johannes.schindelin, nico, gitster, mdl123, git
In-Reply-To: <878wputvnt.fsf@jidanni.org>
jidanni@jidanni.org wrote:
> JK> diff --git a/builtin-unpack-objects.c b/builtin-unpack-objects.c
> OK, I wish you luck in the fruition of the new --dump-delta option, and
> can proofread the man pages involved, otherwise this is no area for
> junior programmer me.
This is rather insane. There's very little data inside of a delta.
That's sort of the point of that level of compression, it takes
up very little disk space and yet describes the change made.
Almost nobody is going to want the delta without the base object
it applies onto. No user of git is going to need that. I'd rather
not carry dead code around in the tree for something nobody will
ever use.
FWIW, most Git deltas are "copy" instructions, they list a position
and count in the base to copy data *from*. These take up less
space then "insert" instructions, where new text is placed into
the file. As the delta generator favors a smaller delta, it tends
to create deltas that use the "copy" instruction more often than the
"insert" instruction. So there is *very* little data in the delta,
just ranges to copy from somewhere else. Without that other place
(the delta base) all you can do is guess about those bits. Which you
can do just as well with a few flips of a fair coin. :-)
--
Shawn.
^ permalink raw reply
* [PATCH] http-push: support full URI in handle_remote_ls_ctx()
From: Kirill A. Korinskiy @ 2009-01-02 6:53 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Kirill A. Korinskiy
In-Reply-To: <1230517935-11299-1-git-send-email-catap@catap.ru>
The program calls remote_ls() to get list of files from the server
over HTTP; handle_remote_ls_ctx() is used to parse its response to
populate "struct remote_ls_ctx" that is returned from remote_ls().
The handle_remote_ls_ctx() function assumed that the server returns a
local path in href field, but RFC 4918 (14.7) demand of support full
URI (e.g. "http://localhost:8080/repo.git").
This resulted in push failure (e.g. git-http-push issues a PROPFIND
request to "/repo.git/alhost:8080/repo.git/refs/" to the server).
Signed-off-by: Kirill A. Korinskiy <catap@catap.ru>
---
http-push.c | 25 +++++++++++++++++++------
1 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/http-push.c b/http-push.c
index 7c6460919bf3eba10c46cede11ffdd9c53fd2dd2..d1749fe2ffd6a59a4eea514997a62b5d7c80b438 100644
--- a/http-push.c
+++ b/http-push.c
@@ -87,6 +87,7 @@ static struct object_list *objects;
struct repo
{
char *url;
+ char *path;
int path_len;
int has_info_refs;
int can_update_info_refs;
@@ -1424,9 +1425,19 @@ static void handle_remote_ls_ctx(struct xml_ctx *ctx, int tag_closed)
ls->userFunc(ls);
}
} else if (!strcmp(ctx->name, DAV_PROPFIND_NAME) && ctx->cdata) {
- ls->dentry_name = xmalloc(strlen(ctx->cdata) -
+ char *path = ctx->cdata;
+ if (*ctx->cdata == 'h') {
+ path = strstr(path, "://");
+ if (path) {
+ path = strchr(path+3, '/');
+ }
+ }
+ if (path) {
+ path += remote->path_len;
+ }
+ ls->dentry_name = xmalloc(strlen(path) -
remote->path_len + 1);
- strcpy(ls->dentry_name, ctx->cdata + remote->path_len);
+ strcpy(ls->dentry_name, path + remote->path_len);
} else if (!strcmp(ctx->name, DAV_PROPFIND_COLLECTION)) {
ls->dentry_flags |= IS_DIR;
}
@@ -2206,10 +2217,11 @@ int main(int argc, char **argv)
if (!remote->url) {
char *path = strstr(arg, "//");
remote->url = arg;
+ remote->path_len = strlen(arg);
if (path) {
- path = strchr(path+2, '/');
- if (path)
- remote->path_len = strlen(path);
+ remote->path = strchr(path+2, '/');
+ if (remote->path)
+ remote->path_len = strlen(remote->path);
}
continue;
}
@@ -2238,8 +2250,9 @@ int main(int argc, char **argv)
rewritten_url = xmalloc(strlen(remote->url)+2);
strcpy(rewritten_url, remote->url);
strcat(rewritten_url, "/");
+ remote->path = rewritten_url + (remote->path - remote->url);
+ remote->path_len++;
remote->url = rewritten_url;
- ++remote->path_len;
}
/* Verify DAV compliance/lock support */
--
1.5.6.5
^ permalink raw reply related
* [EGIT PATCH] Add an import wizard for Eclipse projects as part of clone
From: Robin Rosenberg @ 2009-01-02 6:18 UTC (permalink / raw)
To: spearce; +Cc: git, Robin Rosenberg
In-Reply-To: <20081231155444.GH29071@spearce.org>
This adds an optional page for importing Eclipse style projects
as part of the clone operation. The import page is a stripped
down version of the project import wizard that comes with
eclipse with the added ability to connect the projects to
the Git team provider.
Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
org.spearce.egit.ui/META-INF/MANIFEST.MF | 1 +
.../src/org/spearce/egit/ui/UIText.java | 42 +
.../ui/internal/clone/CloneDestinationPage.java | 36 +-
.../egit/ui/internal/clone/GitCloneWizard.java | 106 +++-
.../ui/internal/clone/GitProjectsImportPage.java | 793 ++++++++++++++++++++
.../components/RepositorySelectionPage.java | 9 +-
.../src/org/spearce/egit/ui/uitext.properties | 15 +
7 files changed, 979 insertions(+), 23 deletions(-)
create mode 100644 org.spearce.egit.ui/src/org/spearce/egit/ui/internal/clone/GitProjectsImportPage.java
diff --git a/org.spearce.egit.ui/META-INF/MANIFEST.MF b/org.spearce.egit.ui/META-INF/MANIFEST.MF
index 092624f..420801b 100644
--- a/org.spearce.egit.ui/META-INF/MANIFEST.MF
+++ b/org.spearce.egit.ui/META-INF/MANIFEST.MF
@@ -19,6 +19,7 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.compare,
org.spearce.jgit,
org.spearce.egit.core,
+ org.eclipse.ui.ide,
org.eclipse.jsch.ui;bundle-version="1.1.100"
Eclipse-LazyStart: true
Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/UIText.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/UIText.java
index b09cc10..124d7a0 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/UIText.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/UIText.java
@@ -17,6 +17,48 @@
*/
public class UIText extends NLS {
/** */
+ public static String WizardProjectsImportPage_ImportProjectsTitle;
+
+ /** */
+ public static String WizardProjectsImportPage_ImportProjectsDescription;
+
+ /** */
+ public static String WizardProjectsImportPage_ProjectsListTitle;
+
+ /** */
+ public static String WizardProjectsImportPage_selectAll;
+
+ /** */
+ public static String WizardProjectsImportPage_deselectAll;
+
+ /** */
+ public static String WizardProjectsImportPage_projectLabel;
+
+ /** */
+ public static String WizardProjectsImportPage_SearchingMessage;
+
+ /** */
+ public static String WizardProjectsImportPage_ProcessingMessage;
+
+ /** */
+ public static String WizardProjectsImportPage_projectsInWorkspace;
+
+ /** */
+ public static String WizardProjectsImportPage_CheckingMessage;
+
+ /** */
+ public static String WizardProjectsImportPage_SelectDialogTitle;
+
+ /** */
+ public static String WizardProjectImportPage_errorMessage;
+
+ /** */
+ public static String WizardProjectsImportPage_CreateProjectsTask;
+
+ /** */
+ public static String WizardProjectsImportPage_enableGit;
+
+ /** */
public static String SharingWizard_windowTitle;
/** */
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/clone/CloneDestinationPage.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/clone/CloneDestinationPage.java
index 5173335..d017b60 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/clone/CloneDestinationPage.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/clone/CloneDestinationPage.java
@@ -2,6 +2,7 @@
* Copyright (C) 2008, Roger C. Soares <rogersoares@intelinet.com.br>
* Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
* Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
+ * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -57,12 +58,15 @@
private Text remoteText;
+ Button showImportWizard;
+
+ String alreadyClonedInto;
+
CloneDestinationPage(final RepositorySelectionPage sp,
final SourceBranchPage bp) {
super(CloneDestinationPage.class.getName());
sourcePage = sp;
branchPage = bp;
-
setTitle(UIText.CloneDestinationPage_title);
final SelectionChangeListener listener = new SelectionChangeListener() {
@@ -82,7 +86,7 @@ public void createControl(final Composite parent) {
createDestinationGroup(panel);
createConfigGroup(panel);
-
+ createWorkbenchGroup(panel);
setControl(panel);
checkPage();
}
@@ -92,6 +96,8 @@ public void setVisible(final boolean visible) {
if (visible)
revalidate();
super.setVisible(visible);
+ if (visible)
+ directoryText.setFocus();
}
private void checkPreviousPagesSelections() {
@@ -165,6 +171,20 @@ public void modifyText(ModifyEvent e) {
});
}
+ private void createWorkbenchGroup(Composite parent) {
+ final Group g = createGroup(parent, "Workspace import");
+ newLabel(g, "Import projects after clone");
+ showImportWizard = new Button(g, SWT.CHECK);
+ showImportWizard.setSelection(true);
+ showImportWizard.setLayoutData(createFieldGridData());
+ showImportWizard.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ checkPage();
+ }
+ });
+ }
+
private static Group createGroup(final Composite parent, final String text) {
final Group g = new Group(parent, SWT.NONE);
final GridLayout layout = new GridLayout();
@@ -222,9 +242,11 @@ setErrorMessage(NLS.bind(UIText.CloneDestinationPage_fieldRequired,
return;
}
final File absoluteFile = new File(dstpath).getAbsoluteFile();
- if (!isEmptyDir(absoluteFile)) {
- setErrorMessage(NLS.bind(UIText.CloneDestinationPage_errorNotEmptyDir,
- absoluteFile.getPath()));
+ if (!absoluteFile.getAbsolutePath().equals(alreadyClonedInto)
+ && !isEmptyDir(absoluteFile)) {
+ setErrorMessage(NLS.bind(
+ UIText.CloneDestinationPage_errorNotEmptyDir, absoluteFile
+ .getPath()));
setPageComplete(false);
return;
}
@@ -316,4 +338,8 @@ private String getSuggestedName() {
return path;
}
+ @Override
+ public boolean canFlipToNextPage() {
+ return super.canFlipToNextPage() && showImportWizard.getSelection();
+ }
}
\ No newline at end of file
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/clone/GitCloneWizard.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/clone/GitCloneWizard.java
index a69dc52..114467f 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/clone/GitCloneWizard.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/clone/GitCloneWizard.java
@@ -2,6 +2,7 @@
* Copyright (C) 2008, Roger C. Soares <rogersoares@intelinet.com.br>
* Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
* Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
+ * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -18,11 +19,13 @@
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.IImportWizard;
import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.PlatformUI;
import org.spearce.egit.core.op.CloneOperation;
import org.spearce.egit.ui.Activator;
import org.spearce.egit.ui.UIIcons;
@@ -41,6 +44,8 @@
private CloneDestinationPage cloneDestination;
+ private GitProjectsImportPage importProject;
+
public void init(IWorkbench arg0, IStructuredSelection arg1) {
setWindowTitle(UIText.GitCloneWizard_title);
setDefaultPageImageDescriptor(UIIcons.WIZBAN_IMPORT_REPO);
@@ -48,6 +53,46 @@ public void init(IWorkbench arg0, IStructuredSelection arg1) {
cloneSource = new RepositorySelectionPage(true);
validSource = new SourceBranchPage(cloneSource);
cloneDestination = new CloneDestinationPage(cloneSource, validSource);
+ importProject = new GitProjectsImportPage() {
+ @Override
+ public void setVisible(boolean visible) {
+ if (visible) {
+ if (cloneDestination.alreadyClonedInto == null) {
+ performClone(false);
+ cloneDestination.alreadyClonedInto = cloneDestination
+ .getDestinationFile().getAbsolutePath();
+ }
+ setProjectsList(cloneDestination.alreadyClonedInto);
+ }
+ super.setVisible(visible);
+ }
+ };
+ }
+
+ @Override
+ public boolean performCancel() {
+ if (cloneDestination.alreadyClonedInto != null) {
+ if (MessageDialog
+ .openQuestion(getShell(), "Aborting clone.",
+ "A complete clone was already made. Do you want to delete it?")) {
+ deleteRecursively(new File(cloneDestination.alreadyClonedInto));
+ }
+ }
+ return true;
+ }
+
+ private void deleteRecursively(File f) {
+ for (File i : f.listFiles()) {
+ if (i.isDirectory()) {
+ deleteRecursively(i);
+ } else {
+ if (!i.delete()) {
+ i.deleteOnExit();
+ }
+ }
+ }
+ if (!f.delete())
+ f.deleteOnExit();
}
@Override
@@ -55,10 +100,24 @@ public void addPages() {
addPage(cloneSource);
addPage(validSource);
addPage(cloneDestination);
+ addPage(importProject);
+ }
+
+ @Override
+ public boolean canFinish() {
+ return cloneDestination.isPageComplete()
+ && !cloneDestination.showImportWizard.getSelection()
+ || importProject.isPageComplete();
}
@Override
public boolean performFinish() {
+ if (!cloneDestination.showImportWizard.getSelection())
+ return performClone(true);
+ return importProject.createProjects();
+ }
+
+ boolean performClone(boolean background) {
final URIish uri = cloneSource.getSelection().getURI();
final boolean allSelected = validSource.isAllSelected();
final Collection<Ref> selectedBranches = validSource
@@ -80,24 +139,37 @@ public boolean performFinish() {
final CloneOperation op = new CloneOperation(uri, allSelected,
selectedBranches, workdir, branch, remoteName);
- final Job job = new Job(NLS.bind(UIText.GitCloneWizard_jobName, uri
- .toString())) {
- @Override
- protected IStatus run(final IProgressMonitor monitor) {
- try {
- op.run(monitor);
- return Status.OK_STATUS;
- } catch (InterruptedException e) {
- return Status.CANCEL_STATUS;
- } catch (InvocationTargetException e) {
- Throwable thr = e.getCause();
- return new Status(IStatus.ERROR, Activator.getPluginId(),
- 0, thr.getMessage(), thr);
+ if (background) {
+ final Job job = new Job(NLS.bind(UIText.GitCloneWizard_jobName, uri
+ .toString())) {
+ @Override
+ protected IStatus run(final IProgressMonitor monitor) {
+ try {
+ op.run(monitor);
+ return Status.OK_STATUS;
+ } catch (InterruptedException e) {
+ return Status.CANCEL_STATUS;
+ } catch (InvocationTargetException e) {
+ Throwable thr = e.getCause();
+ return new Status(IStatus.ERROR, Activator
+ .getPluginId(), 0, thr.getMessage(), thr);
+ }
}
+ };
+ job.setUser(true);
+ job.schedule();
+ return true;
+ } else {
+ try {
+ PlatformUI.getWorkbench().getProgressService().run(false, true,
+ op);
+ return true;
+ } catch (Exception e) {
+ Activator.logError("Failed to clone", e);
+ MessageDialog.openError(getShell(), "Failed clone", e
+ .toString());
+ return false;
}
- };
- job.setUser(true);
- job.schedule();
- return true;
+ }
}
}
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/clone/GitProjectsImportPage.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/clone/GitProjectsImportPage.java
new file mode 100644
index 0000000..ece585a
--- /dev/null
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/clone/GitProjectsImportPage.java
@@ -0,0 +1,793 @@
+package org.spearce.egit.ui.internal.clone;
+
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * Copyright (C) 2007, Martin Oberhuber (martin.oberhuber@windriver.com)
+ * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * See LICENSE for the full license text, also available.
+ *******************************************************************************/
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTreeViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
+import org.eclipse.ui.internal.ide.StatusUtil;
+import org.eclipse.ui.internal.wizards.datatransfer.WizardProjectsImportPage;
+import org.eclipse.ui.statushandlers.StatusManager;
+import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider;
+import org.spearce.egit.core.op.ConnectProviderOperation;
+import org.spearce.egit.ui.Activator;
+import org.spearce.egit.ui.UIText;
+
+/**
+ * The GitWizardProjectsImportPage is the page that allows the user to import
+ * projects from a particular location. This is a modified copy of
+ * {@link WizardProjectsImportPage}
+ */
+public class GitProjectsImportPage extends WizardPage {
+
+ /**
+ * The name of the folder containing metadata information for the workspace.
+ */
+ public static final String METADATA_FOLDER = ".metadata"; //$NON-NLS-1$
+
+ /**
+ * The import structure provider.
+ */
+ private IImportStructureProvider structureProvider;
+
+ class ProjectRecord {
+ File projectSystemFile;
+
+ String projectName;
+
+ Object parent;
+
+ int level;
+
+ IProjectDescription description;
+
+ /**
+ * Create a record for a project based on the info in the file.
+ *
+ * @param file
+ */
+ ProjectRecord(File file) {
+ projectSystemFile = file;
+ setProjectName();
+ }
+
+ /**
+ * @param parent
+ * The parent folder of the .project file
+ * @param level
+ * The number of levels deep in the provider the file is
+ */
+ ProjectRecord(Object parent, int level) {
+ this.parent = parent;
+ this.level = level;
+ setProjectName();
+ }
+
+ /**
+ * Set the name of the project based on the projectFile.
+ */
+ private void setProjectName() {
+ try {
+ // If we don't have the project name try again
+ if (projectName == null) {
+ IPath path = new Path(projectSystemFile.getPath());
+ // if the file is in the default location, use the directory
+ // name as the project name
+ if (isDefaultLocation(path)) {
+ projectName = path.segment(path.segmentCount() - 2);
+ description = IDEWorkbenchPlugin.getPluginWorkspace()
+ .newProjectDescription(projectName);
+ } else {
+ description = IDEWorkbenchPlugin.getPluginWorkspace()
+ .loadProjectDescription(path);
+ projectName = description.getName();
+ }
+
+ }
+ } catch (CoreException e) {
+ // no good couldn't get the name
+ }
+ }
+
+ /**
+ * Returns whether the given project description file path is in the
+ * default location for a project
+ *
+ * @param path
+ * The path to examine
+ * @return Whether the given path is the default location for a project
+ */
+ private boolean isDefaultLocation(IPath path) {
+ // The project description file must at least be within the project,
+ // which is within the workspace location
+ if (path.segmentCount() < 2)
+ return false;
+ return path.removeLastSegments(2).toFile().equals(
+ Platform.getLocation().toFile());
+ }
+
+ /**
+ * Get the name of the project
+ *
+ * @return String
+ */
+ public String getProjectName() {
+ return projectName;
+ }
+
+ /**
+ * Gets the label to be used when rendering this project record in the
+ * UI.
+ *
+ * @return String the label
+ * @since 3.4
+ */
+ public String getProjectLabel() {
+ if (description == null)
+ return projectName;
+
+ String path = projectSystemFile == null ? structureProvider
+ .getLabel(parent) : projectSystemFile.getParent();
+
+ return NLS.bind(UIText.WizardProjectsImportPage_projectLabel,
+ projectName, path);
+ }
+ }
+
+ private CheckboxTreeViewer projectsList;
+
+ private ProjectRecord[] selectedProjects = new ProjectRecord[0];
+
+ private IProject[] wsProjects;
+
+ // The last selected path to minimize searches
+ private String lastPath;
+
+ // The last time that the file or folder at the selected path was modified
+ // to mimize searches
+ private long lastModified;
+
+ private Button shareCheckBox;
+
+ private boolean share;
+
+ /**
+ * Creates a new project creation wizard page.
+ */
+ public GitProjectsImportPage() {
+ this("gitWizardExternalProjectsPage"); //$NON-NLS-1$
+ }
+
+ /**
+ * Create a new instance of the receiver.
+ *
+ * @param pageName
+ */
+ public GitProjectsImportPage(String pageName) {
+ super(pageName);
+ setPageComplete(false);
+ setTitle(UIText.WizardProjectsImportPage_ImportProjectsTitle);
+ setDescription(UIText.WizardProjectsImportPage_ImportProjectsDescription);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets
+ * .Composite)
+ */
+ public void createControl(Composite parent) {
+
+ initializeDialogUnits(parent);
+
+ Composite workArea = new Composite(parent, SWT.NONE);
+ setControl(workArea);
+
+ workArea.setLayout(new GridLayout());
+ workArea.setLayoutData(new GridData(GridData.FILL_BOTH
+ | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));
+
+ createProjectsRoot(workArea);
+ createProjectsList(workArea);
+ createOptionsArea(workArea);
+ Dialog.applyDialogFont(workArea);
+
+ }
+
+ /**
+ * Create the area with the extra options.
+ *
+ * @param workArea
+ */
+ private void createOptionsArea(Composite workArea) {
+ Composite optionsGroup = new Composite(workArea, SWT.NONE);
+ optionsGroup.setLayout(new GridLayout());
+ optionsGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ shareCheckBox = new Button(optionsGroup, SWT.CHECK);
+ shareCheckBox.setText(UIText.WizardProjectsImportPage_enableGit);
+ shareCheckBox.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ shareCheckBox.setSelection(share = true);
+ shareCheckBox.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ share = shareCheckBox.getSelection();
+ }
+ });
+ }
+
+ /**
+ * Create the checkbox list for the found projects.
+ *
+ * @param workArea
+ */
+ private void createProjectsList(Composite workArea) {
+
+ Label title = new Label(workArea, SWT.NONE);
+ title.setText(UIText.WizardProjectsImportPage_ProjectsListTitle);
+
+ Composite listComposite = new Composite(workArea, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 2;
+ layout.marginWidth = 0;
+ layout.makeColumnsEqualWidth = false;
+ listComposite.setLayout(layout);
+
+ listComposite.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
+ | GridData.GRAB_VERTICAL | GridData.FILL_BOTH));
+
+ projectsList = new CheckboxTreeViewer(listComposite, SWT.BORDER);
+ GridData listData = new GridData(GridData.GRAB_HORIZONTAL
+ | GridData.GRAB_VERTICAL | GridData.FILL_BOTH);
+ projectsList.getControl().setLayoutData(listData);
+
+ projectsList.setContentProvider(new ITreeContentProvider() {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java
+ * .lang.Object)
+ */
+ public Object[] getChildren(Object parentElement) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.viewers.IStructuredContentProvider#getElements
+ * (java.lang.Object)
+ */
+ public Object[] getElements(Object inputElement) {
+ return getValidProjects();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java
+ * .lang.Object)
+ */
+ public boolean hasChildren(Object element) {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.viewers.ITreeContentProvider#getParent(java
+ * .lang.Object)
+ */
+ public Object getParent(Object element) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+ */
+ public void dispose() {
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse
+ * .jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ public void inputChanged(Viewer viewer, Object oldInput,
+ Object newInput) {
+ }
+
+ });
+
+ projectsList.setLabelProvider(new LabelProvider() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
+ */
+ public String getText(Object element) {
+ return ((ProjectRecord) element).getProjectLabel();
+ }
+ });
+
+ projectsList.addCheckStateListener(new ICheckStateListener() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged
+ * (org.eclipse.jface.viewers.CheckStateChangedEvent)
+ */
+ public void checkStateChanged(CheckStateChangedEvent event) {
+ setPageComplete(projectsList.getCheckedElements().length > 0);
+ }
+ });
+
+ projectsList.setInput(this);
+ projectsList.setComparator(new ViewerComparator());
+ createSelectionButtons(listComposite);
+ }
+
+ /**
+ * Create the selection buttons in the listComposite.
+ *
+ * @param listComposite
+ */
+ private void createSelectionButtons(Composite listComposite) {
+ Composite buttonsComposite = new Composite(listComposite, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ buttonsComposite.setLayout(layout);
+
+ buttonsComposite.setLayoutData(new GridData(
+ GridData.VERTICAL_ALIGN_BEGINNING));
+
+ Button selectAll = new Button(buttonsComposite, SWT.PUSH);
+ selectAll.setText(UIText.WizardProjectsImportPage_selectAll);
+ selectAll.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ projectsList.setCheckedElements(selectedProjects);
+ setPageComplete(projectsList.getCheckedElements().length > 0);
+ }
+ });
+ Dialog.applyDialogFont(selectAll);
+ setButtonLayoutData(selectAll);
+
+ Button deselectAll = new Button(buttonsComposite, SWT.PUSH);
+ deselectAll.setText(UIText.WizardProjectsImportPage_deselectAll);
+ deselectAll.addSelectionListener(new SelectionAdapter() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse
+ * .swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent e) {
+
+ projectsList.setCheckedElements(new Object[0]);
+ setPageComplete(false);
+ }
+ });
+ Dialog.applyDialogFont(deselectAll);
+ setButtonLayoutData(deselectAll);
+
+ }
+
+ /**
+ * Create the area where you select the root directory for the projects.
+ *
+ * @param workArea
+ * Composite
+ */
+ private void createProjectsRoot(Composite workArea) {
+
+ // project specification group
+ Composite projectGroup = new Composite(workArea, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 3;
+ layout.makeColumnsEqualWidth = false;
+ layout.marginWidth = 0;
+ projectGroup.setLayout(layout);
+ projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IDialogPage. Set the focus on path
+ * fields when page becomes visible.
+ */
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+ }
+
+ /**
+ * Update the list of projects based on path.
+ *
+ * @param path
+ */
+ void setProjectsList(final String path) {
+ // on an empty path empty selectedProjects
+ if (path == null || path.length() == 0) {
+ setMessage(UIText.WizardProjectsImportPage_ImportProjectsDescription);
+ selectedProjects = new ProjectRecord[0];
+ projectsList.refresh(true);
+ projectsList.setCheckedElements(selectedProjects);
+ setPageComplete(projectsList.getCheckedElements().length > 0);
+ lastPath = path;
+ return;
+ }
+
+ final File directory = new File(path);
+ long modified = directory.lastModified();
+ if (path.equals(lastPath) && lastModified == modified) {
+ // since the file/folder was not modified and the path did not
+ // change, no refreshing is required
+ return;
+ }
+
+ lastPath = path;
+ lastModified = modified;
+
+ try {
+ getContainer().run(true, true, new IRunnableWithProgress() {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.operation.IRunnableWithProgress#run(org
+ * .eclipse.core.runtime.IProgressMonitor)
+ */
+ public void run(IProgressMonitor monitor) {
+
+ monitor.beginTask(
+ UIText.WizardProjectsImportPage_SearchingMessage,
+ 100);
+ selectedProjects = new ProjectRecord[0];
+ Collection files = new ArrayList();
+ monitor.worked(10);
+ if (directory.isDirectory()) {
+
+ if (!collectProjectFilesFromDirectory(files, directory,
+ null, monitor)) {
+ return;
+ }
+ Iterator filesIterator = files.iterator();
+ selectedProjects = new ProjectRecord[files.size()];
+ int index = 0;
+ monitor.worked(50);
+ monitor
+ .subTask(UIText.WizardProjectsImportPage_ProcessingMessage);
+ while (filesIterator.hasNext()) {
+ File file = (File) filesIterator.next();
+ selectedProjects[index] = new ProjectRecord(file);
+ index++;
+ }
+ } else {
+ monitor.worked(60);
+ }
+ monitor.done();
+ }
+
+ });
+ } catch (InvocationTargetException e) {
+ IDEWorkbenchPlugin.log(e.getMessage(), e);
+ } catch (InterruptedException e) {
+ // Nothing to do if the user interrupts.
+ }
+
+ projectsList.refresh(true);
+ projectsList.setCheckedElements(getValidProjects());
+ if (getValidProjects().length < selectedProjects.length) {
+ setMessage(UIText.WizardProjectsImportPage_projectsInWorkspace,
+ WARNING);
+ } else {
+ setMessage(UIText.WizardProjectsImportPage_ImportProjectsDescription);
+ }
+ setPageComplete(projectsList.getCheckedElements().length > 0);
+ }
+
+ /**
+ * Collect the list of .project files that are under directory into files.
+ *
+ * @param files
+ * @param directory
+ * @param directoriesVisited
+ * Set of canonical paths of directories, used as recursion guard
+ * @param monitor
+ * The monitor to report to
+ * @return boolean <code>true</code> if the operation was completed.
+ */
+ private boolean collectProjectFilesFromDirectory(Collection files,
+ File directory, Set directoriesVisited, IProgressMonitor monitor) {
+
+ if (monitor.isCanceled()) {
+ return false;
+ }
+ monitor.subTask(NLS.bind(
+ UIText.WizardProjectsImportPage_CheckingMessage, directory
+ .getPath()));
+ File[] contents = directory.listFiles();
+ if (contents == null)
+ return false;
+
+ // Initialize recursion guard for recursive symbolic links
+ if (directoriesVisited == null) {
+ directoriesVisited = new HashSet();
+ try {
+ directoriesVisited.add(directory.getCanonicalPath());
+ } catch (IOException exception) {
+ StatusManager.getManager().handle(
+ StatusUtil.newStatus(IStatus.ERROR, exception
+ .getLocalizedMessage(), exception));
+ }
+ }
+
+ // first look for project description files
+ final String dotProject = IProjectDescription.DESCRIPTION_FILE_NAME;
+ for (int i = 0; i < contents.length; i++) {
+ File file = contents[i];
+ if (file.isFile() && file.getName().equals(dotProject)) {
+ files.add(file);
+ // don't search sub-directories since we can't have nested
+ // projects
+ return true;
+ }
+ }
+ // no project description found, so recurse into sub-directories
+ for (int i = 0; i < contents.length; i++) {
+ if (contents[i].isDirectory()) {
+ if (!contents[i].getName().equals(METADATA_FOLDER)) {
+ try {
+ String canonicalPath = contents[i].getCanonicalPath();
+ if (!directoriesVisited.add(canonicalPath)) {
+ // already been here --> do not recurse
+ continue;
+ }
+ } catch (IOException exception) {
+ StatusManager.getManager().handle(
+ StatusUtil.newStatus(IStatus.ERROR, exception
+ .getLocalizedMessage(), exception));
+
+ }
+ collectProjectFilesFromDirectory(files, contents[i],
+ directoriesVisited, monitor);
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Create the selected projects
+ *
+ * @return boolean <code>true</code> if all project creations were
+ * successful.
+ */
+ boolean createProjects() {
+ final Object[] selected = projectsList.getCheckedElements();
+ WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
+ protected void execute(IProgressMonitor monitor)
+ throws InvocationTargetException, InterruptedException {
+ try {
+ monitor.beginTask("", selected.length); //$NON-NLS-1$
+ if (monitor.isCanceled()) {
+ throw new OperationCanceledException();
+ }
+ for (int i = 0; i < selected.length; i++) {
+ createExistingProject((ProjectRecord) selected[i],
+ new SubProgressMonitor(monitor, 1));
+ }
+ } finally {
+ monitor.done();
+ }
+ }
+ };
+ // run the new project creation operation
+ try {
+ getContainer().run(true, true, op);
+ } catch (InterruptedException e) {
+ return false;
+ } catch (InvocationTargetException e) {
+ // one of the steps resulted in a core exception
+ Throwable t = e.getTargetException();
+ String message = UIText.WizardProjectImportPage_errorMessage;
+ IStatus status;
+ if (t instanceof CoreException) {
+ status = ((CoreException) t).getStatus();
+ } else {
+ status = new Status(IStatus.ERROR,
+ IDEWorkbenchPlugin.IDE_WORKBENCH, 1, message, t);
+ }
+ Activator.logError(message, t);
+ ErrorDialog.openError(getShell(), message, null, status);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Create the project described in record. If it is successful return true.
+ *
+ * @param record
+ * @param monitor
+ * @return boolean <code>true</code> if successful
+ * @throws InvocationTargetException
+ * @throws InterruptedException
+ */
+ private boolean createExistingProject(final ProjectRecord record,
+ IProgressMonitor monitor) throws InvocationTargetException,
+ InterruptedException {
+ String projectName = record.getProjectName();
+ final IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ final IProject project = workspace.getRoot().getProject(projectName);
+ if (record.description == null) {
+ // error case
+ record.description = workspace.newProjectDescription(projectName);
+ IPath locationPath = new Path(record.projectSystemFile
+ .getAbsolutePath());
+
+ // If it is under the root use the default location
+ if (Platform.getLocation().isPrefixOf(locationPath)) {
+ record.description.setLocation(null);
+ } else {
+ record.description.setLocation(locationPath);
+ }
+ } else {
+ record.description.setName(projectName);
+ }
+
+ try {
+ monitor.beginTask(
+ UIText.WizardProjectsImportPage_CreateProjectsTask, 100);
+ project.create(record.description, new SubProgressMonitor(monitor,
+ 30));
+ int openTicks = share ? 50 : 70;
+ project.open(IResource.BACKGROUND_REFRESH, new SubProgressMonitor(
+ monitor, openTicks));
+ if (share) {
+ ConnectProviderOperation connectProviderOperation = new ConnectProviderOperation(
+ project, null);
+ connectProviderOperation
+ .run(new SubProgressMonitor(monitor, 20));
+ }
+ } catch (CoreException e) {
+ throw new InvocationTargetException(e);
+ } finally {
+ monitor.done();
+ }
+
+ return true;
+ }
+
+ /**
+ * Method used for test suite.
+ *
+ * @return CheckboxTreeViewer the viewer containing all the projects found
+ */
+ public CheckboxTreeViewer getProjectsList() {
+ return projectsList;
+ }
+
+ /**
+ * Retrieve all the projects in the current workspace.
+ *
+ * @return IProject[] array of IProject in the current workspace
+ */
+ private IProject[] getProjectsInWorkspace() {
+ if (wsProjects == null) {
+ wsProjects = IDEWorkbenchPlugin.getPluginWorkspace().getRoot()
+ .getProjects();
+ }
+ return wsProjects;
+ }
+
+ /**
+ * Get the array of valid project records that can be imported from the
+ * source workspace or archive, selected by the user. If a project with the
+ * same name exists in both the source workspace and the current workspace,
+ * it will not appear in the list of projects to import and thus cannot be
+ * selected for import.
+ *
+ * Method declared public for test suite.
+ *
+ * @return ProjectRecord[] array of projects that can be imported into the
+ * workspace
+ */
+ public ProjectRecord[] getValidProjects() {
+ List validProjects = new ArrayList();
+ for (int i = 0; i < selectedProjects.length; i++) {
+ if (!isProjectInWorkspace(selectedProjects[i].getProjectName())) {
+ validProjects.add(selectedProjects[i]);
+ }
+ }
+ return (ProjectRecord[]) validProjects
+ .toArray(new ProjectRecord[validProjects.size()]);
+ }
+
+ /**
+ * Determine if the project with the given name is in the current workspace.
+ *
+ * @param projectName
+ * String the project name to check
+ * @return boolean true if the project with the given name is in this
+ * workspace
+ */
+ private boolean isProjectInWorkspace(String projectName) {
+ if (projectName == null) {
+ return false;
+ }
+ IProject[] workspaceProjects = getProjectsInWorkspace();
+ for (int i = 0; i < workspaceProjects.length; i++) {
+ if (projectName.equals(workspaceProjects[i].getName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/components/RepositorySelectionPage.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/components/RepositorySelectionPage.java
index 86cf6ec..4f02c95 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/components/RepositorySelectionPage.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/components/RepositorySelectionPage.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2007, 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
* Copyright (C) 2008, Roger C. Soares <rogersoares@intelinet.com.br>
* Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
* Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
@@ -660,4 +660,11 @@ private void updateAuthGroup() {
break;
}
}
+
+ @Override
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+ if (visible)
+ uriText.setFocus();
+ }
}
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/uitext.properties b/org.spearce.egit.ui/src/org/spearce/egit/ui/uitext.properties
index 22e29c2..98ce80f 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/uitext.properties
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/uitext.properties
@@ -15,6 +15,21 @@
## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
##
+WizardProjectsImportPage_projectLabel={0} ({1})
+WizardProjectsImportPage_ImportProjectsTitle=Import Projects
+WizardProjectsImportPage_ImportProjectsDescription=Import projects from cloned repository into workbench
+WizardProjectsImportPage_ProjectsListTitle=&Projects
+WizardProjectsImportPage_selectAll = &Select All
+WizardProjectsImportPage_deselectAll = &Deselect All
+WizardProjectsImportPage_SearchingMessage = Searching for projects
+WizardProjectsImportPage_ProcessingMessage = Processing results
+WizardProjectsImportPage_projectsInWorkspace = Some projects were hidden because they exist in the workspace directory
+WizardProjectsImportPage_CheckingMessage = Checking: {0}
+WizardProjectsImportPage_SelectDialogTitle = Select root directory of the projects to import
+WizardProjectImportPage_errorMessage = Creation Problems
+WizardProjectsImportPage_CreateProjectsTask = Creating Projects
+WizardProjectsImportPage_enableGit = Enable Git Team operations on imported projects
+
SharingWizard_windowTitle=Configure Git Repository
SharingWizard_failed=Failed to initialize Git team provider.
--
1.6.1.rc3.56.gd0306
^ permalink raw reply related
* Re: git has modified files after clean checkout
From: Caleb Cushing @ 2009-01-02 5:49 UTC (permalink / raw)
To: Thomas Rast; +Cc: David Aguilar, git
In-Reply-To: <200901012048.13630.trast@student.ethz.ch>
> Do you have any .gitattributes? A few days ago, ludde on IRC bumped
> into the problem that git-checkout applies the .gitattributes that are
> present in the tree *before* the checkout. Naturally this means that
> the .gitattributes do not apply at all during the first checkout at
> the end of cloning. In ludde's case, this caused git-blame to think
> the file had all line endings changed compared to the index version.
>
no, no .gitattributes to my knowledge (file doesn't exist). but it's
not just during the first checkout.
# On branch regen2
# Your branch is ahead of 'funtoo/funtoo.org' by 1 commit.
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
#
# modified: app-admin/petrovich/files/petrovich-1.0.0-gentoo.diff
# modified: app-cdr/mode2cdmaker/files/mode2cdmaker-1.5.1-gentoo.patch
# modified: app-crypt/mhash/files/mhash-0.9.9-mutils-align.patch
# modified: app-crypt/rainbowcrack/files/rainbowcrack-1.2+gcc-4.3.patch
# modified: app-crypt/rainbowcrack/files/rainbowcrack-1.2-share.patch
# modified: app-crypt/rainbowcrack/files/rainbowcrack-1.2-types.patch
# modified: app-editors/leo/files/leoConfig.py.patch
# modified:
app-emacs/aspectj4emacs/files/aspectj4emacs-1.1_beta2-browse-url-new-window-gentoo.patch
# modified:
app-emacs/aspectj4emacs/files/aspectj4emacs-1.1_beta2-compile-log-gentoo.patch
...
that continues on for a while, all that was done was a git pull funtoo
funtoo.org
I haven't had time to test 1.6.1 yet
--
Caleb Cushing
http://xenoterracide.blogspot.com
^ permalink raw reply
* Re: git-branch --print-current
From: David Aguilar @ 2009-01-02 4:26 UTC (permalink / raw)
To: Karl Chen; +Cc: Git mailing list
In-Reply-To: <quack.20090101T1928.lthzliaqtdf@roar.cs.berkeley.edu>
On Thu, Jan 1, 2009 at 7:28 PM, Karl Chen <quarl@cs.berkeley.edu> wrote:
>
> How about an option to git-branch that just prints the name of
> the current branch for scripts' sake? To replace:
>
> git branch --no-color 2>/dev/null | perl -ne '/^[*] (.*)/ && print $1'
The justification I've heard before is that 'git branch' is a
porcelain and thus we shouldn't rely on its output for scripting
purposes.
You might want to use 'git symbolic-ref' instead.
$ git symbolic-ref HEAD
refs/heads/master
$ git symbolic-ref HEAD | sed -e 's,refs/heads/,,'
master
--
David
^ permalink raw reply
* git-branch --print-current
From: Karl Chen @ 2009-01-02 3:28 UTC (permalink / raw)
To: Git mailing list
How about an option to git-branch that just prints the name of the
current branch for scripts' sake? To replace:
git branch --no-color 2>/dev/null | perl -ne '/^[*] (.*)/ && print $1'
^ permalink raw reply
* Re: [PATCH] gitweb: Handle actions with no project in evaluate_path_info
From: Devin Doucette @ 2009-01-02 2:21 UTC (permalink / raw)
To: Giuseppe Bilotta; +Cc: Jakub Narebski, git, Petr Baudis
In-Reply-To: <cb7bb73a0901011646n6a1368caq797a5f2849daec77@mail.gmail.com>
On Thu, Jan 1, 2009 at 5:46 PM, Giuseppe Bilotta
<giuseppe.bilotta@gmail.com> wrote:
> Actually, the early bailout was sort of intentional. The problem is
> the ambiguity: does git.example.com/opml refer to the opml project, or
> does it refer to the opml action?
Good point. Though my patch does not break any existing functionality,
it does not fix the case where a project matches the action.
> HOWEVER, href() *does* create the opml action as git.example.com/opml,
> so gitweb is currently broken in the sense that ti doesn't correctly
> parse its own pathinfo output. So the question is: shall we go with
> this patch, preventing pathinfo from working for projects named like a
> no-project gitweb action, or should we fix href() to not generate
> pathinfo unless project is defined?
A variation of the latter approach is to modify href() to use pathinfo
if there is a project or there is no project matching the name of the
action. The only downside to this approach is that a URI that refers to
an action when first generated could resolve to a project in the future,
if a project of the same name were added.
--
Devin Doucette
^ permalink raw reply
* Re: git-difftool
From: Ping Yin @ 2009-01-02 1:59 UTC (permalink / raw)
To: markus.heidelberg; +Cc: Matthieu Moy, David Aguilar, git
In-Reply-To: <200901020104.01522.markus.heidelberg@web.de>
On Fri, Jan 2, 2009 at 8:04 AM, Markus Heidelberg
<markus.heidelberg@web.de> wrote:
> Ping Yin, 01.01.2009:
>> On Thu, Jan 1, 2009 at 12:04 AM, Matthieu Moy <Matthieu.Moy@imag.fr> wrote:
>> > David Aguilar <davvid@gmail.com> writes:
>> >
>> >> The usual use case for this script is when you have either
>> >> staged or unstaged changes and you'd like to see the changes
>> >> in a side-by-side diff viewer (e.g. xxdiff, tkdiff, etc).
>> >>
>> >> git difftool [<filename>*]
>> >
>> > Is it not a complex way of saying
>> >
>> > GIT_EXTERNAL_DIFF=xxdiff git diff
>>
>> $ cat mydiff
>> #!/bin/bash
>> exec vimdiff $2 $5
>>
>> then i run
>>
>> $ GIT_EXTERNAL_DIFF=mydiff git diff
>>
>> but it gives me the error
>> Vim: Warning: Output is not to a terminal
>
> Just the warning and everything else works? For me the display is
> totally screwed up and the commands don't really work because of the
> pager. I have to add GIT_PAGER="" to get it working.
>
Thanks. With GIT_PAGER="" it works now.
^ permalink raw reply
* Re: [PATCH 0/3] Teach Git about the patience diff algorithm
From: Linus Torvalds @ 2009-01-02 1:56 UTC (permalink / raw)
To: Adeodato Simó
Cc: Johannes Schindelin, Pierre Habouzit, davidel, Francis Galiegue,
Git ML
In-Reply-To: <20090101204652.GA26128@chistera.yi.org>
On Thu, 1 Jan 2009, Adeodato Simó wrote:
>
> For me, the cases where I find patience output to be of substantial
> higher readability are those involving a rewrite of several consecutive
> paragraphs (i.e., lines of code separated by blank lines). Compare:
I don't think that's a "patience diff" issue.
That's simply an issue of merging consecutive diff fragments together if
they are close-by, and that's independent of the actual diff algorithm
itself.
> I'll note that in this particular case, `git diff` yielded the very same
> results with or without --patience. I don't know why that is, Johannes?
> I'll also note that /usr/bin/diff produces (in this case) something
> closer to patience than to git.
See above - I really don't think this has anything to do with "patience vs
non-patience". It's more akin to the things we do for our merge conflict
markers: if we have two merge conflicts next to each other, with just a
couple of lines in between, we coalesce the merge conflicts into one
larger one instead.
We don't do that for regular diffs - they're always kept minimal (ok, not
really minimal, but as close to minimal as the algorithm finds them).
See commit f407f14deaa14ebddd0d27238523ced8eca74393 for the git merge
conflict merging. We _could_ do similar things for regular diffs. It's
sometimes useful, sometimes not.
Linus
^ permalink raw reply
* Re: [PATCH] Pass --upload-pack and --receive-pack through submodules.
From: Jason Riedy @ 2009-01-02 1:44 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vy6xuhhbx.fsf@gitster.siamese.dyndns.org>
And Junio C. Hamano writes:
> Do we (and can we) assume that the remote repositories submodules fetch
> from all reside on the same host and can share the same values for these
> parameters? Shouldn't these instead be specified in the configuration
> files for the submodules, if they need to be nonstandard values?
git does not and (for me) should not make the assumption above.
I'm fetching different pieces from different administrative
domains where I also have push access. While I could clone them
all into one place, that adds another level of repositories I'd
have to keep up-to-date.
Essentially, I'm collecting experimental libraries and drivers
into one build tree. My intent is to record exactly what is
being built on multiple machines while being able to push local
build configurations back to my central superproject. Then I can
make a version with pull-only remote URLs[1] for others to
duplicate the setup for my experiments.
I suppose I could clone the submodules by hand and then use git
submodule add. But then I'll have to build the structure by hand
(with my own wrapper) everywhere I use the supermodule. At that
point, using git submodule becomes a tad silly. Or I could set
up the superproject with pull-only URLs and modify the
configurations with a separate wrapper. Seemed like adding the
two options to git submodule was easier.
Jason
Footnotes:
[1] Or ask for separate pull- and push-urls in git remote. But
I haven't thought that through.
^ permalink raw reply
* Re: [RFC PATCH] builtin-apply: prevent non-explicit permission changes
From: Junio C Hamano @ 2009-01-02 0:56 UTC (permalink / raw)
To: Alexander Potashev; +Cc: Git Mailing List
In-Reply-To: <20090101221720.GA5603@myhost>
Alexander Potashev <aspotashev@gmail.com> writes:
> On 05:00 Thu 01 Jan , Junio C Hamano wrote:
>> Alexander Potashev <aspotashev@gmail.com> writes:
> ...
>> > @@ -2447,6 +2447,7 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
>> > if (st_mode != patch->old_mode)
>> > fprintf(stderr, "warning: %s has type %o, expected %o\n",
>> > old_name, st_mode, patch->old_mode);
>> > + patch->new_mode = st_mode;
>>
>> Can you do this unconditionally, overwriting whatever we read from the
>> patch header metainfo lines?
>
> Do you mean overwriting of 'patch->new_mode' right after patch parsing?
My question was if we should assign st_mode to new_mode _unconditionally_
here, even when patch->new_mode has already been read from the explicit
mode change line (i.e. "new mode ", line not "index "line) of the patch
input.
The call-chain of the program looks like this:
-> apply_patch()
-> parse_chunk()
-> find_header()
* initialize new_mode and old_mode to 0
-> parse_git_header()
* set new_mode and old_mode from the patch metainfo, i.e.
"new mode", "old mode" and "index" lines.
-> parse_single_patch()
-> check_patch_list()
-> check_patch()
-> check_preimage()
* make sure there is no local mods
* warn if old_mode read from the patch (i.e. the preimage file
the patch submitter used to prepare the patch against) does not
match what we have
* warn about mode inconsistency (e.g. the patch submitter thinks
the mode should be 0644 but our tree has 0755).
-> apply_data()
-> write_out_results()
-> write_out_one_result(0)
* delete old
-> write_out_one_result(1)
* create new
Currently the mode 100644 on the "index" line in a patch is handled
exactly in the same way as having "old mode 100644" and "new mode 100644"
lines in the metainfo. The patch submitter claims to have started from
100644 and he claims that he wants to have 100644 as the result. That is
why there is a warning in check_patch().
If we stop reading the new mode from the "index" line (but we still read
"old_mode" there) without any other change you made in your patch, what
breaks (i.e. without the patch->new_mode assignment hunk)? I haven't
followed the codepath too closely, and I suspect you found some cases
where new_mode stays 0 as initialized, and that may be the reason you have
this assignment.
But the assignment being unconditional bothered me a lot.
I tend to agree that the current "The final mode bits I want to have on
this path is this" semantics we give to the "index" line is much less
useful and less sane and it is a good idea to redefine it as "FYI, the
copy I made this patch against had this mode bits. I do not intend to
change the mode bits of the path with this patch."
builtin-apply.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git c/builtin-apply.c w/builtin-apply.c
index 07244b0..a8f75ed 100644
--- c/builtin-apply.c
+++ w/builtin-apply.c
@@ -630,7 +630,7 @@ static int gitdiff_index(const char *line, struct patch *patch)
memcpy(patch->new_sha1_prefix, line, len);
patch->new_sha1_prefix[len] = 0;
if (*ptr == ' ')
- patch->new_mode = patch->old_mode = strtoul(ptr+1, NULL, 8);
+ patch->old_mode = strtoul(ptr+1, NULL, 8);
return 0;
}
@@ -2447,6 +2447,8 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
if (st_mode != patch->old_mode)
fprintf(stderr, "warning: %s has type %o, expected %o\n",
old_name, st_mode, patch->old_mode);
+ if (!patch->new_mode)
+ patch->new_mode = st_mode;
return 0;
is_new:
^ permalink raw reply related
* Re: [PATCH] gitweb: Handle actions with no project in evaluate_path_info
From: Giuseppe Bilotta @ 2009-01-02 0:46 UTC (permalink / raw)
To: Jakub Narebski; +Cc: Devin Doucette, git, Petr Baudis
In-Reply-To: <200901020058.30748.jnareb@gmail.com>
On Fri, Jan 2, 2009 at 12:58 AM, Jakub Narebski <jnareb@gmail.com> wrote:
> Truth to be told we parse action parameter in path_info only since
> d8c2882 (gitweb: parse project/action/hash_base:filename PATH_INFO)
> by Giuseppe Bilotta (CC-ed; I think he is correct person to give
> Ack for this patch). Earlier only "default" actions could be expressed
> using only path_info, and project-less 'opml' and 'project_index'
> actions are not default actions for projectless URL, so there was no
> such problem then.
Actually, the early bailout was sort of intentional. The problem is
the ambiguity: does git.example.com/opml refer to the opml project, or
does it refer to the opml action?
HOWEVER, href() *does* create the opml action as git.example.com/opml,
so gitweb is currently broken in the sense that ti doesn't correctly
parse its own pathinfo output. So the question is: shall we go with
this patch, preventing pathinfo from working for projects named like a
no-project gitweb action, or should we fix href() to not generate
pathinfo unless project is defined?
>> - return unless $project;
>> - $input_params{'project'} = $project;
>> + $input_params{'project'} = $project if $project;
Note that if this patch is accepted, we probably need an appropriate
patch in href() anyway to use query params for projects named like
no-project actions.
--
Giuseppe "Oblomov" Bilotta
^ permalink raw reply
* Re: [PATCH] doc/git-send-email: mention sendemail.cc config variable
From: Thomas Rast @ 2009-01-02 0:43 UTC (permalink / raw)
To: markus.heidelberg; +Cc: git, gitster
In-Reply-To: <200901020040.41399.markus.heidelberg@web.de>
[-- Attachment #1: Type: text/plain, Size: 353 bytes --]
Markus Heidelberg wrote:
> I just tested it with --dry-run: the command line options for all three
> header lines (to cc bcc) override the corresponding config settings. So
> the formulation is correct: the settings are only default values.
Indeed, you're right. Apologies for the false alarm.
--
Thomas Rast
trast@{inf,student}.ethz.ch
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* Re: [PATCH] Documentation/git-merge: at least one <remote> not two
From: Sitaram Chamarty @ 2009-01-02 0:25 UTC (permalink / raw)
To: git
In-Reply-To: <7vk59ehg7l.fsf@gitster.siamese.dyndns.org>
On 2009-01-01, Junio C Hamano <gitster@pobox.com> wrote:
> * Is it a good idea to standardize on "one or more" semantics? I suspect
> we would rather want to standardize on "zero or more", because it would
> be more natural to say:
>
> $ git diff [--] <paths>...
>
> to mean "You can give paths if you want to but you do not have to". If
> ellipses meant "one or more", you have to say this instead:
>
> $ git diff [--] [<paths>...]
For what it is worth, I have always understood "..." to mean
"more of the preceding", meaning "one or more". That is
your first example above.
Zero or more is your second syntax above, because the whole
thing is in brackets, and hence completely optional.
In regex terms (to me anyway):
a? == [a]
a+ == a...
a* == [a...]
^ permalink raw reply
* Re: git-difftool
From: Markus Heidelberg @ 2009-01-02 0:13 UTC (permalink / raw)
To: Matthieu Moy; +Cc: David Aguilar, git
In-Reply-To: <vpq8wpux61c.fsf@bauges.imag.fr>
Matthieu Moy, 01.01.2009:
> "David Aguilar" <davvid@gmail.com> writes:
>
> > Hmm... in theory, yes, but in practice, no.
> > xxdiff is too gimp to handle what 'git diff' hands it =)
>
> As done with "vimdiff" in another message, simply write a one-liner
> wrapper script that calls xxdiff $2 $3, and call this wrapper script.
This works with GUI tools, but not with console tools. GVim works, Vim
doesn't.
And invoking
git difftool
is by far more convenient than
GIT_EXTERNAL_DIFF=vimdiff git diff
Markus
^ permalink raw reply
* Re: [PATCH] Documentation/git-bundle.txt: Dumping contents of any bundle
From: jidanni @ 2009-01-02 0:10 UTC (permalink / raw)
To: peff; +Cc: johannes.schindelin, nico, gitster, mdl123, spearce, git
In-Reply-To: <20090101234815.GA9049@coredump.intra.peff.net>
JK> diff --git a/builtin-unpack-objects.c b/builtin-unpack-objects.c
OK, I wish you luck in the fruition of the new --dump-delta option, and
can proofread the man pages involved, otherwise this is no area for
junior programmer me.
^ permalink raw reply
* Re: git-difftool
From: Markus Heidelberg @ 2009-01-02 0:04 UTC (permalink / raw)
To: Ping Yin; +Cc: Matthieu Moy, David Aguilar, git
In-Reply-To: <46dff0320812312338i5a3ee0cem702a6b67ef76e48c@mail.gmail.com>
Ping Yin, 01.01.2009:
> On Thu, Jan 1, 2009 at 12:04 AM, Matthieu Moy <Matthieu.Moy@imag.fr> wrote:
> > David Aguilar <davvid@gmail.com> writes:
> >
> >> The usual use case for this script is when you have either
> >> staged or unstaged changes and you'd like to see the changes
> >> in a side-by-side diff viewer (e.g. xxdiff, tkdiff, etc).
> >>
> >> git difftool [<filename>*]
> >
> > Is it not a complex way of saying
> >
> > GIT_EXTERNAL_DIFF=xxdiff git diff
>
> $ cat mydiff
> #!/bin/bash
> exec vimdiff $2 $5
>
> then i run
>
> $ GIT_EXTERNAL_DIFF=mydiff git diff
>
> but it gives me the error
> Vim: Warning: Output is not to a terminal
Just the warning and everything else works? For me the display is
totally screwed up and the commands don't really work because of the
pager. I have to add GIT_PAGER="" to get it working.
Markus
^ permalink raw reply
* Re: [PATCH] gitweb: Handle actions with no project in evaluate_path_info
From: Jakub Narebski @ 2009-01-01 23:58 UTC (permalink / raw)
To: Devin Doucette; +Cc: git, Petr Baudis, Giuseppe Bilotta
In-Reply-To: <a899d7ef0812272326j1a407c30k936bf8d8975c9063@mail.gmail.com>
On Sun, 28 Dec 2008, Devin Doucette wrote:
> The action would not be set if no valid project was found in
> path_info. Removing the return if the project was not specified fixes
> the project_index and opml actions when using path_info.
>
Thanks for catching this.
Truth to be told we parse action parameter in path_info only since
d8c2882 (gitweb: parse project/action/hash_base:filename PATH_INFO)
by Giuseppe Bilotta (CC-ed; I think he is correct person to give
Ack for this patch). Earlier only "default" actions could be expressed
using only path_info, and project-less 'opml' and 'project_index'
actions are not default actions for projectless URL, so there was no
such problem then.
> Signed-off-by: Devin Doucette <devin@doucette.cc>
> ---
> gitweb/gitweb.perl | 3 +--
> 1 files changed, 1 insertions(+), 2 deletions(-)
>
> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
> index 8f574c7..b6a8ea9 100755
> --- a/gitweb/gitweb.perl
> +++ b/gitweb/gitweb.perl
> @@ -552,8 +552,7 @@ sub evaluate_path_info {
> while ($project && !check_head_link("$projectroot/$project")) {
> $project =~ s,/*[^/]*$,,;
> }
> - return unless $project;
> - $input_params{'project'} = $project;
> + $input_params{'project'} = $project if $project;
>
> # do not change any parameters if an action is given using the query string
> return if $input_params{'action'};
> --
> 1.6.1.rc4
>
--
Jakub Narebski
Poland
^ 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