Git development
 help / color / mirror / Atom feed
* [EGIT PATCH] Showing abbreviated commit hash of the versions in Compare editor.
From: Roger C. Soares @ 2008-01-08  1:15 UTC (permalink / raw)
  To: git


Signed-off-by: Roger C. Soares <rogersoares@intelinet.com.br>
---
Some more patches, please evaluate.
Don't know what others are working on,
but right now I'm missing a search functionality so
this will probably be my next egit little feature.

cheers

 .../GitCompareFileRevisionEditorInput.java         |   12 ++++++++++++
 .../spearce/egit/ui/internal/GitResourceNode.java  |    5 +++++
 2 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/GitCompareFileRevisionEditorInput.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/GitCompareFileRevisionEditorInput.java
index eaba1fa..403fdc1 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/GitCompareFileRevisionEditorInput.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/GitCompareFileRevisionEditorInput.java
@@ -152,6 +152,18 @@ public class GitCompareFileRevisionEditorInput extends CompareEditorInput {
 
 	private void initLabels(ICompareInput input) {
 		CompareConfiguration cc = getCompareConfiguration();
+		if(left != null && left instanceof GitResourceNode) {
+			String ci = ((GitResourceNode)left).getContentIdentifier();
+			if(ci != null) {
+				cc.setLeftLabel(ci.substring(0, 7) + "..");
+			}
+		}
+		if(right != null && right instanceof GitResourceNode) {
+			String ci = ((GitResourceNode)right).getContentIdentifier();
+			if(ci != null) {
+				cc.setRightLabel(ci.substring(0, 7) + "..");
+			}
+		}
 		if (getLeftRevision() != null) {
 			String leftLabel = getFileRevisionLabel(getLeftRevision());
 			cc.setLeftLabel(leftLabel);
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/GitResourceNode.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/GitResourceNode.java
index e19cef5..f25855a 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/GitResourceNode.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/GitResourceNode.java
@@ -21,6 +21,7 @@ import org.spearce.jgit.lib.TreeEntry;
 public class GitResourceNode extends BufferedContent implements IStructureComparator, ITypedElement {
 	TreeEntry entry;
 	GitResourceNode[] children;
+	String contentIdentifier;
 
 	public GitResourceNode(TreeEntry e) {
 		entry = e;
@@ -28,6 +29,7 @@ public class GitResourceNode extends BufferedContent implements IStructureCompar
 
 	public GitResourceNode(IFileRevision file) {
 		this(file instanceof GitCommitFileRevision ? ((GitCommitFileRevision)file).getTreeEntry() : null);
+		contentIdentifier = ((GitCommitFileRevision)file).getContentIdentifier();
 	}
 
 	public Object[] getChildren() {
@@ -100,5 +102,8 @@ public class GitResourceNode extends BufferedContent implements IStructureCompar
 		}
 	}
 
+	public String getContentIdentifier() {
+		return contentIdentifier;
+	}
 }
 
-- 
1.5.3.7

^ permalink raw reply related

* [EGIT PATCH] Showing commit info like the CVS plugin instead of tooltips.
From: Roger C. Soares @ 2008-01-08  1:20 UTC (permalink / raw)
  To: git

Tooltips for the info were annoying, especially on MacOS where the tooltip center is your pointer location.
It is now possible to copy&paste data.
Like the CVS plugin, there's a menu to show/hide views. Thought it doesn't save in the preferences store for now.

Signed-off-by: Roger C. Soares <rogersoares@intelinet.com.br>
---
 .../src/org/spearce/egit/ui/GitHistoryPage.java    |  361 +++++++++++++++-----
 .../src/org/spearce/egit/ui/UIText.java            |    4 +
 .../src/org/spearce/egit/ui/uitext.properties      |    4 +
 3 files changed, 277 insertions(+), 92 deletions(-)

diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/GitHistoryPage.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/GitHistoryPage.java
index 3738dfd..ae404cf 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/GitHistoryPage.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/GitHistoryPage.java
@@ -17,6 +17,7 @@
 package org.spearce.egit.ui;
 
 import java.io.IOException;
+import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
@@ -37,10 +38,14 @@ import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.action.IMenuListener;
 import org.eclipse.jface.action.IMenuManager;
 import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
 import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.TextViewer;
 import org.eclipse.jface.viewers.ColumnWeightData;
 import org.eclipse.jface.viewers.ILazyContentProvider;
 import org.eclipse.jface.viewers.StructuredSelection;
@@ -48,12 +53,11 @@ import org.eclipse.jface.viewers.TableLayout;
 import org.eclipse.jface.viewers.TableViewer;
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
 import org.eclipse.swt.events.MouseEvent;
 import org.eclipse.swt.events.MouseListener;
-import org.eclipse.swt.events.MouseMoveListener;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
@@ -72,6 +76,8 @@ import org.eclipse.team.internal.ui.history.DialogHistoryPageSite;
 import org.eclipse.team.ui.history.HistoryPage;
 import org.eclipse.team.ui.history.IHistoryCompareAdapter;
 import org.eclipse.team.ui.history.IHistoryPageSite;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.part.IPageSite;
 import org.spearce.egit.core.GitProvider;
 import org.spearce.egit.core.internal.mapping.GitCommitFileRevision;
 import org.spearce.egit.core.internal.mapping.GitFileHistory;
@@ -92,16 +98,24 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 	private static final String PREF_SHOWALLREPOVERSIONS = "org.spearce.egit.ui.githistorypage.showallrepoversions";
 	private static final String PREF_SHOWALLPROJECTVERSIONS = "org.spearce.egit.ui.githistorypage.showallprojectversions";
 	private static final String PREF_SHOWALLFOLDERVERSIONS = "org.spearce.egit.ui.githistorypage.showallfolderversions";
+	/* private */static final SimpleDateFormat DATETIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+	/* private */static final SimpleDateFormat DATETIMETZ_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
 
-	private Composite localComposite;
+	private SashForm localComposite;
+	private SashForm revisionInfoComposite;
 
-	private TableViewer viewer;
+	/* private */TableViewer viewer;
+	/* private */TextViewer revDetailTextViewer;
+	/* private */TextViewer revCommentTextViewer;
+	/* private */IAction toggleCommentWrapAction;
+	/* private */IAction toggleRevDetailAction;
+	/* private */IAction toggleRevCommentAction;
 
-	private Table table;
+	/* private */Table table;
 
-	private List<IFileRevision> fileRevisions;
+	/* private */List<IFileRevision> fileRevisions;
 
-	protected boolean hintShowDiffNow;
+	/* private */boolean hintShowDiffNow;
 
 	private boolean showAllProjectVersions;
 
@@ -127,7 +141,8 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 	}
 
 	public void createControl(Composite parent) {
-		localComposite = new Composite(parent, SWT.NONE);
+		localComposite = new SashForm(parent, SWT.VERTICAL);
+
 		GridLayout layout = new GridLayout();
 		layout.marginHeight = 0;
 		layout.marginWidth = 0;
@@ -138,6 +153,10 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 
 		createTable(localComposite);
 
+		revisionInfoComposite = new SashForm(localComposite, SWT.HORIZONTAL);
+		createRevDetailTextViewer(revisionInfoComposite);
+		createRevCommentTextViewer(revisionInfoComposite);
+
 		IHistoryPageSite parentSite = getHistoryPageSite();
 		if (parentSite != null && parentSite instanceof DialogHistoryPageSite)
 			parentSite.setSelectionProvider(viewer);
@@ -149,6 +168,7 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 		table.addMouseListener(new MouseListener() {
 		
 			public void mouseUp(MouseEvent e) {
+				return;
 			}
 		
 			public void mouseDown(MouseEvent e) {
@@ -156,25 +176,11 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 			}
 		
 			public void mouseDoubleClick(MouseEvent e) {
+				return;
 			}
 		
 		});
 
-		table.addMouseMoveListener(new MouseMoveListener() {
-			TableItem lastItem;
-			public void mouseMove(MouseEvent e) {
-				TableItem item = table.getItem(new Point(e.x,e.y));
-				if (item != null && item!=lastItem) {
-					IFileRevision rev = (IFileRevision) item.getData();
-					if (rev == null)
-						return;
-					String toolTipText = formatRevisionToolTipText(rev);
-					table.setToolTipText(toolTipText);
-				}
-				lastItem = item;
-			}
-		});
-
 		table.addSelectionListener(new SelectionAdapter() {
 			public void widgetSelected(SelectionEvent e) {
 				// update the current
@@ -184,6 +190,12 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 					selection2[i] = (IFileRevision) selection[i].getData();
 				}
 
+				// Updates the revision info text viewers
+				cleanRevisionInfoTextViewers();
+				if(selection2.length == 1) {
+					setRevisionInfoTextViewers(selection2[0]);
+				}
+
 				compareAction.setCurrentFileRevision(fileRevisions.get(0));
 				compareAction.selectionChanged(new StructuredSelection(
 						selection2));
@@ -280,33 +292,92 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 		showAllFolderVersionsAction.setChecked(isShowAllFolderVersions());
 		getSite().getActionBars().getToolBarManager().add(
 				showAllFolderVersionsAction);
+
+		toggleCommentWrapAction = new Action(UIText.ResourceHistory_toggleCommentWrap) {
+			public void run() {
+				updateResourceHistoryComposites();
+			}
+		};
+		toggleCommentWrapAction.setChecked(true);
+
+		toggleRevDetailAction = new Action(UIText.ResourceHistory_toggleRevDetail) {
+			public void run() {
+				updateResourceHistoryComposites();
+			}
+		};
+		toggleRevDetailAction.setChecked(true);
+
+		toggleRevCommentAction = new Action(UIText.ResourceHistory_toggleRevComment) {
+			public void run() {
+				updateResourceHistoryComposites();
+			}
+		};
+		toggleRevCommentAction.setChecked(true);
+
+		IActionBars actionBars = getSite().getActionBars();
+		IMenuManager menuManager = actionBars.getMenuManager();
+		if (menuManager != null) {
+			menuManager.add(toggleCommentWrapAction);
+			menuManager.add(new Separator());
+			menuManager.add(toggleRevDetailAction);
+			menuManager.add(toggleRevCommentAction);
+			menuManager.add(new Separator());
+		}
+		actionBars.updateActionBars();
+		updateResourceHistoryComposites();
+
+		localComposite.setWeights(new int[] {65, 35});
+		revisionInfoComposite.setWeights(new int[] {40, 60});
+	}
+
+	/* private */void updateResourceHistoryComposites() {
+		boolean commentWrap = toggleCommentWrapAction.isChecked();
+		boolean showRevDetail = toggleRevDetailAction.isChecked();
+		boolean showRevComment = toggleRevCommentAction.isChecked();
+
+		revCommentTextViewer.getTextWidget().setWordWrap(commentWrap);
+
+		if(showRevDetail && showRevComment) {
+			localComposite.setMaximizedControl(null);
+			revisionInfoComposite.setMaximizedControl(null);
+		} else {
+			if(!(showRevDetail || showRevComment)) {
+				localComposite.setMaximizedControl(table);
+			} else if(showRevDetail) {
+				localComposite.setMaximizedControl(null);
+				revisionInfoComposite.setMaximizedControl(revDetailTextViewer.getControl());
+			} else {
+				localComposite.setMaximizedControl(null);
+				revisionInfoComposite.setMaximizedControl(revCommentTextViewer.getControl());
+			}
+		}
 	}
 
-	private boolean isShowAllRepoVersions() {
+	/* private */boolean isShowAllRepoVersions() {
 		return showAllRepoVersions;
 	}
 
-	protected void setShowAllRepoVersions(boolean showAllRepoVersions) {
+	/* private */void setShowAllRepoVersions(boolean showAllRepoVersions) {
 		this.showAllRepoVersions = showAllRepoVersions;
 		Activator.getDefault().getPreferenceStore().setValue(
 				PREF_SHOWALLREPOVERSIONS, showAllRepoVersions);
 	}
 
-	private boolean isShowAllProjectVersions() {
+	/* private */boolean isShowAllProjectVersions() {
 		return showAllProjectVersions;
 	}
 
-	protected void setShowAllProjectVersions(boolean showAllProjectVersions) {
+	/* private */void setShowAllProjectVersions(boolean showAllProjectVersions) {
 		this.showAllProjectVersions = showAllProjectVersions;
 		Activator.getDefault().getPreferenceStore().setValue(
 				PREF_SHOWALLPROJECTVERSIONS, showAllProjectVersions);
 	}
 
-	private boolean isShowAllFolderVersions() {
+	/* private */boolean isShowAllFolderVersions() {
 		return showAllFolderVersions;
 	}
 
-	protected void setShowAllFolderVersion(boolean showAllFolderVersions) {
+	/* private */void setShowAllFolderVersion(boolean showAllFolderVersions) {
 		this.showAllFolderVersions = showAllFolderVersions;
 		Activator.getDefault().getPreferenceStore().setValue(
 				PREF_SHOWALLFOLDERVERSIONS, showAllFolderVersions);
@@ -392,7 +463,7 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 				Date d = new Date(element.getTimestamp());
 				if (d.getTime() == -1)
 					return "";
-				return d.toString();
+				return DATETIME_FORMAT.format(d);
 			}
 			if (columnIndex == 4)
 				return element.getAuthor();
@@ -411,6 +482,166 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 		}
 	}
 
+	private void createRevDetailTextViewer(SashForm composite) {
+		revDetailTextViewer = new TextViewer(composite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.READ_ONLY);
+	}
+
+	private void createRevCommentTextViewer(SashForm composite) {
+		revCommentTextViewer = new TextViewer(composite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.READ_ONLY);
+	}
+
+	/* private */void setRevisionInfoTextViewers(IFileRevision rev) {
+		StringBuilder revisionInfo = new StringBuilder();
+		if (appliedPatches != null) {
+			String id = rev.getContentIdentifier();
+			if (!id.equals("Workspace") && !id.equals("Index")) {
+				StGitPatch patch = (StGitPatch) appliedPatches
+						.get(new ObjectId(id));
+				if (patch != null) {
+					revisionInfo.append("Patch: ");
+					revisionInfo.append(patch.getName());
+				}
+			} else {
+				revisionInfo.append(id.toString());
+			}
+		}
+		if (revisionInfo.length() == 0) {
+			revisionInfo.append("Commit: ");
+			revisionInfo.append(rev.getContentIdentifier());
+		}
+
+		// Gets the tags for this revision.
+		// TODO: Understand this better and see if there's a simpler/shared way to do it.
+		IProject project = ((IResource) getInput()).getProject();
+		RepositoryMapping repositoryMapping = RepositoryMapping.getMapping(project);
+		Map<ObjectId,Tag[]> newtags = new HashMap<ObjectId,Tag[]>();
+		try {
+			for (String name : repositoryMapping.getRepository().getTags()) {
+				Tag t = repositoryMapping.getRepository().mapTag(name);
+				Tag[] samecommit = newtags.get(t.getObjId());
+				if (samecommit==null) { 
+					samecommit = new Tag[] { t };
+				} else {
+					Tag[] n=new Tag[samecommit.length+1];
+					for (int j=0; j<samecommit.length; ++j)
+						n[j] = samecommit[j];
+					n[n.length-1] = t;
+					samecommit = n;
+				}
+				newtags.put(t.getObjId(), samecommit);
+			}
+
+			String id = rev.getContentIdentifier();
+			if (!id.equals("Workspace") && !id.equals("Index")) {
+				ObjectId oid = new ObjectId(id);
+				StringBuilder b=new StringBuilder();
+				if (tags != null) {
+					Tag[] matching = tags.get(oid);
+					if (matching != null) {
+						for (Tag t : matching) {
+							if (b.length() > 0)
+								b.append(", ");
+							String tag = t.getTag();
+							b.append(tag);
+						}
+					}
+				}
+				if(b.length() > 0) {
+					revisionInfo.append("\nTags: ");
+					revisionInfo.append(b);
+				}
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+		// Gets the branches for this revision.
+		// TODO: Branches should always show all the branches from a commit.
+		Map<ObjectId, String[]> newBranches = new HashMap<ObjectId, String[]>();
+		try {
+			for (String branch : repositoryMapping.getRepository().getBranches()) {
+				ObjectId id = repositoryMapping.getRepository().resolve(branch);
+				String[] samecommit = newBranches.get(id);
+				if (samecommit == null) {
+					samecommit = new String[] { branch };
+				} else {
+					String[] n=new String[samecommit.length + 1];
+					for (int j=0; j<samecommit.length; ++j)
+						n[j] = samecommit[j];
+					n[n.length-1] = branch;
+					samecommit = n;
+				}
+				newBranches.put(id, samecommit);
+			}
+			String[] samecommit = newBranches.get(currentHead);
+			if (samecommit == null) {
+				samecommit = new String[] { "HEAD" };
+			} else {
+				String[] n=new String[samecommit.length + 1];
+				for (int j=0; j<samecommit.length; ++j)
+					n[j] = samecommit[j];
+				n[n.length-1] = "HEAD";
+				samecommit = n;
+			}
+			newBranches.put(currentHead, samecommit);
+			branches = newBranches;
+
+			String id = rev.getContentIdentifier();
+			if (branches != null) {
+				StringBuilder b=new StringBuilder();
+				ObjectId oid = new ObjectId(id);
+				String[] matching = branches.get(oid);
+				if (matching != null) {
+					for (String t : matching) {
+						if (b.length() > 0)
+							b.append(", ");
+						if (t.startsWith("refs/heads/"))
+							t = t.substring(11);
+						b.append(t);
+					}
+				}
+				if(b.length() > 0) {
+					revisionInfo.append("\nBranches: ");
+					revisionInfo.append(b);
+				}
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+		revisionInfo.append("\nAuthor: ");
+		revisionInfo.append(rev.getAuthor());
+		revisionInfo.append("\nDate: ");
+		revisionInfo.append(DATETIMETZ_FORMAT.format(new Date(rev.getTimestamp())));
+
+		String comment = rev.getComment();
+		revDetailTextViewer.setDocument(new Document(revisionInfo.toString()));
+		revCommentTextViewer.setDocument(new Document(comment));
+
+		// Adds the first comment line in the status line.
+		int enterIndex = comment.indexOf("\n");
+		if(enterIndex > 0) {
+			comment = comment.substring(0, enterIndex);
+		}
+		IPageSite workbenchPageSite = getHistoryPageSite().getWorkbenchPageSite();
+		if (workbenchPageSite != null) {
+			workbenchPageSite.getActionBars().getStatusLineManager().setMessage(comment);
+		}
+	}
+
+	/* private */void cleanRevisionInfoTextViewers() {
+		if(revDetailTextViewer != null && revCommentTextViewer != null) {
+			revDetailTextViewer.setDocument(new Document(""));
+			revCommentTextViewer.setDocument(new Document(""));
+
+			// Cleans the status line
+			IPageSite workbenchPageSite = getHistoryPageSite().getWorkbenchPageSite();
+			if (workbenchPageSite != null) {
+				workbenchPageSite.getActionBars().getStatusLineManager().setMessage(null);
+			}
+		}
+	}
+
 	private void createTable(Composite composite) {
 		table = new Table(composite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI
 				| SWT.FULL_SELECTION | SWT.VIRTUAL);
@@ -556,10 +787,10 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 		viewer.setInput(getInput());
 	}
 
-	private Map appliedPatches;
+	/* private */Map appliedPatches;
 	ObjectId currentHead;
-	private Map<ObjectId,Tag[]> tags;
-	private Map<ObjectId, String[]> branches;
+	/* private */Map<ObjectId,Tag[]> tags;
+	/* private */Map<ObjectId, String[]> branches;
 	GitHistoryLabelProvider lp = new GitHistoryLabelProvider();
 
 	class HistoryRefreshJob extends Job {
@@ -662,6 +893,8 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 				table.getDisplay().asyncExec(new Runnable() {
 				
 					public void run() {
+						cleanRevisionInfoTextViewers();
+
 						table.removeAll();
 						table.setItemCount(fileRevisions.size());
 						table.setData("X");
@@ -720,6 +953,7 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 		}
 
 		public void dispose() {
+			return;
 		}
 
 		public void updateElement(int index) {
@@ -757,7 +991,7 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 		col.setResizable(true);
 		col.setText(TeamUIMessages.GenericHistoryTableProvider_RevisionTime);
 		// X col.addSelectionListener(headerListener);
-		((TableLayout) table.getLayout()).addColumnData(new ColumnWeightData(30,
+		((TableLayout) table.getLayout()).addColumnData(new ColumnWeightData(20,
 				true));
 
 		// author
@@ -773,7 +1007,7 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 		col.setResizable(true);
 		col.setText(TeamUIMessages.GenericHistoryTableProvider_Comment);
 		// X col.addSelectionListener(headerListener);
-		((TableLayout) table.getLayout()).addColumnData(new ColumnWeightData(35,
+		((TableLayout) table.getLayout()).addColumnData(new ColumnWeightData(45,
 				true));
 	}
 
@@ -821,61 +1055,4 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 		// TODO Auto-generated method stub
 	}
 
-	/**
-	 * Formats the revision description to be displayed in the tooltip.
-	 *
-	 * @param rev
-	 *            the revision to be displayed
-	 * @return formatted description
-	 */
-	protected String formatRevisionToolTipText(IFileRevision rev) {
-		String commitStr = null;
-		if (appliedPatches != null) {
-			String id = rev.getContentIdentifier();
-			if (!id.equals("Workspace") && !id.equals("Index")) {
-				StGitPatch patch = (StGitPatch) appliedPatches
-						.get(new ObjectId(id));
-				if (patch != null)
-					commitStr = "Patch: " + patch.getName();
-			} else {
-				commitStr = id.toString();
-			}
-		}
-		if (commitStr == null)
-			commitStr = "Commit: " + rev.getContentIdentifier();
-
-		// The tooltip window is usually
-		// narrower
-		// than the comment. Remove soft returns
-		// to
-		// avoid short lines like in
-		// this
-		// example
-		String niceComment = unwrapComment(rev.getComment());
-		String toolTipText = commitStr + "\nAuthor: " + rev.getAuthor()
-				+ "\nDate: " + new Date(rev.getTimestamp()) + "\n\n"
-				+ niceComment;
-		return toolTipText;
-	}
-
-	/**
-	 * Remove soft returns (single \n) from the string. Keep hard returns
-	 * between paragraphs (two \n).
-	 *
-	 * @param origComment
-	 * @return reformated comment
-	 */
-	private static String unwrapComment(String origComment) {
-		if (origComment == null)
-			return null;
-		String paragraphs[] = origComment.split("\n\\s*\n");
-		StringBuffer result = new StringBuffer();
-		for (int i = 0; i < paragraphs.length; i++) {
-			result.append(paragraphs[i].replaceAll("\n", " "));
-			if (i < paragraphs.length - 1)
-				result.append("\n\n");
-		}
-		return result.toString();
-	}
-
 }
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 cdbe8bb..b714c1d 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
@@ -39,6 +39,10 @@ public class UIText extends NLS {
 
 	public static String QuickDiff_failedLoading;
 
+	public static String ResourceHistory_toggleCommentWrap;
+	public static String ResourceHistory_toggleRevDetail;
+	public static String ResourceHistory_toggleRevComment;
+
 	static {
 		initializeMessages(UIText.class.getPackage().getName() + ".uitext",
 				UIText.class);
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 75e975b..f45f4d2 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
@@ -28,3 +28,7 @@ ExistingOrNewPage_createNew=Create a new Git repository for this project
 
 Decorator_failedLazyLoading=Resource decorator failed to load tree contents on demand.
 QuickDiff_failedLoading=Quick diff failed to obtain file data.
+
+ResourceHistory_toggleCommentWrap=Wrap Comments
+ResourceHistory_toggleRevDetail=Show Revision Details
+ResourceHistory_toggleRevComment=Show Revision Comment
\ No newline at end of file
-- 
1.5.3.7

^ permalink raw reply related

* Re: [PATCH] Allow git-mergetool to handle paths with a leading space
From: Theodore Tso @ 2008-01-08  1:19 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Rogan Dawes, Git Mailing List
In-Reply-To: <7v8x320zom.fsf@gitster.siamese.dyndns.org>

On Mon, Jan 07, 2008 at 01:09:45AM -0800, Junio C Hamano wrote:
> Rogan Dawes <rogan@dawes.za.net> writes:
> 
> I did not however apply your patch to my tree tonight, as Ted as
> the original and the primary author of the script may have
> better ideas, and/or future directions for the patch.  He can
> simply just Ack your patch if he chooses to.

Acked-by: "Theodore Ts'o" <tytso@mit.edu>

> In the longer term, I'd probably suggest redoing the entire
> command in a NUL safe scripting language (or even C, especially
> if pressed by mingw or msys folks) to eliminate the issue
> altogether, though.  But that would definitely be a post 1.5.4
> item.

Yeah, we eventually need to redo "git mergetool" in C.  One of the
reasons for that is at the moment it can't take advantage of the
rename detection machinery, so in the case where there is a merge
conflict involving a file that has been renamed in one of the two
branches, "git mergetool" doesn't do the right thing.

Even if it would be possible to expose the rename machinery in a form
that would be convenient for a shell script, it's past time to rewrite
it in C, I think....

						- Ted

^ permalink raw reply

* [PATCH] Added recurse command to git submodule
From: Imran M Yousuf @ 2008-01-08  3:14 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 4114 bytes --]

Added a recurse command to git-submodule. Using this recurse command
any git command (for example, git-status, git-diff, git-checkout) can
be performed from the top level to all its submodules at any depth; if
the module has not been initialized and updated (that is git sumodule
init and git submodule update) the script will take care of that too.

I needed this feature especially for diff, status and pull; as I am
working on a multi module maven project with each module having
separate repository due to architecture and future extensibility.

Following is the diff with git-submdoule version 1.5.3.7. I also
attached the diff and the modified file in the attachment.

diff --git a/git-submodule b/git-submodule
index b91d626..e819152 100755
--- a/git-submodule
+++ b/git-submodule
@@ -1,10 +1,11 @@
 #!/bin/sh
 #
 # git-submodules.sh: add, init, update or list git submodules
+# or recurse any git command over the submodules recursively.
 #
 # Copyright (c) 2007 Lars Hjemli

-USAGE='[--quiet] [--cached] [add <repo> [-b
branch]|status|init|update] [--] [<path>...]'
+USAGE='[[--quiet] [--cached] [add <repo> [-b
branch]|status|init|update] [--] [<path>...]|[recurse [-v] command
arguments ...]]'
 . git-sh-setup
 require_work_tree

@@ -251,6 +252,78 @@ modules_list()
 	done
 }

+# Simply checks whether the submodule is initialized
+# or not. If not initialized it does so.
+initializeSubModule() {
+	if [ ! -d "$1"/.git ]; then
+		if [ $recurse_verbose -eq 1 ]; then
+			echo Initializing and updating "$1"
+		fi
+		git-submodule init "$1"; git-submodule update "$1"
+	fi
+}
+
+# This actually traverses the module; checks
+# whether the module is initialized or not.
+# if not initialized, then done so and then the
+# intended command is evaluated. Then it
+# recursively goes into it modules.
+traverseModule() {
+	current_dir=`pwd`
+	dir_path="$current_dir:$dir_path"
+	initializeSubModule "$1"
+        cd "$1"
+	if [ $recurse_verbose -eq 1 ]; then
+		echo Working in mod $1 @ `pwd` with $2
+	fi
+        eval "$2"
+	if [ -f .gitmodules ]; then
+                for mod_path in `grep "path =" .gitmodules | awk
'{print $3}'`; do
+                        traverseModule "$mod_path" "$2"
+                done
+        fi
+	old_dir=$(echo $dir_path | cut -d':' -f1-1)
+	length_old_dir=`expr "$old_dir" : '.*'`
+	cd $old_dir
+	index=$(echo "$length_old_dir+2" | bc)
+	dir_path=`echo $dir_path $index | awk '{print substr($1, $2)}'`
+}
+
+# Propagates or recurses over all the submodules at any
+# depth with any git command, e.g. git-clone, git-status,
+# git-commit etc., with the arguments supplied exactly as
+# it would have been supplied to the command otherwise.
+# This actually starts the recursive propagation
+propagate() {
+	project_home=`pwd`
+	echo Project Home: $project_home
+	if [ -d $project_home/.git/ ]; then
+		git_command=$1
+		shift
+		command_arguments=""
+		for arg in "$@"; do
+			if [ `expr index "$arg" ' '` -gt 0 ]; then
+				arg="\"$arg\""
+			fi
+			command_arguments="$command_arguments $arg"
+		done
+		if [ $recurse_verbose -eq 1 ]; then
+			echo GIT Command git-$git_command with arguments\($#\) "$command_arguments"
+		fi
+		main_command="git-$git_command $command_arguments"
+		eval $main_command
+		if [ -f .gitmodules ]; then
+			for mod_path in `grep "path =" .gitmodules | awk '{print $3}'`; do
+				traverseModule $mod_path "$main_command"
+			done
+		fi
+	else
+		echo $project_home not a git repo thus exiting
+		exit
+	fi
+}
+
+recurse_verbose=0
 while test $# != 0
 do
 	case "$1" in
@@ -286,6 +359,17 @@ do
 	-*)
 		usage
 		;;
+	recurse)
+		recurse=1
+		case "$2" in
+			-v)
+				recurse_verbose=1
+				shift
+				;;
+		esac
+		shift
+		break
+		;;
 	*)
 		break
 		;;
@@ -303,17 +387,21 @@ case "$add,$branch" in
 	;;
 esac

-case "$add,$init,$update,$status,$cached" in
-1,,,,)
+
+case "$add,$init,$update,$recurse,$status,$cached" in
+1,,,,,)
 	module_add "$@"
 	;;
-,1,,,)
+,1,,,,)
 	modules_init "$@"
 	;;
-,,1,,)
+,,1,,,)
 	modules_update "$@"
 	;;
-,,,*,*)
+,,,1,,)
+	propagate "$@"
+	;;
+,,,,*,*)
 	modules_list "$@"
 	;;
 *)

-- 
Imran M Yousuf

[-- Attachment #2: git-submodule-diff-1.5.3.7.txt --]
[-- Type: text/plain, Size: 3425 bytes --]

diff --git a/git-submodule b/git-submodule
index b91d626..e819152 100755
--- a/git-submodule
+++ b/git-submodule
@@ -1,10 +1,11 @@
 #!/bin/sh
 #
 # git-submodules.sh: add, init, update or list git submodules
+# or recurse any git command over the submodules recursively.
 #
 # Copyright (c) 2007 Lars Hjemli
 
-USAGE='[--quiet] [--cached] [add <repo> [-b branch]|status|init|update] [--] [<path>...]'
+USAGE='[[--quiet] [--cached] [add <repo> [-b branch]|status|init|update] [--] [<path>...]|[recurse [-v] command arguments ...]]'
 . git-sh-setup
 require_work_tree
 
@@ -251,6 +252,78 @@ modules_list()
 	done
 }
 
+# Simply checks whether the submodule is initialized
+# or not. If not initialized it does so.
+initializeSubModule() {
+	if [ ! -d "$1"/.git ]; then
+		if [ $recurse_verbose -eq 1 ]; then
+			echo Initializing and updating "$1"
+		fi
+		git-submodule init "$1"; git-submodule update "$1"
+	fi
+}
+
+# This actually traverses the module; checks
+# whether the module is initialized or not.
+# if not initialized, then done so and then the
+# intended command is evaluated. Then it
+# recursively goes into it modules.
+traverseModule() {
+	current_dir=`pwd`
+	dir_path="$current_dir:$dir_path"
+	initializeSubModule "$1"
+        cd "$1"
+	if [ $recurse_verbose -eq 1 ]; then
+		echo Working in mod $1 @ `pwd` with $2
+	fi
+        eval "$2"
+	if [ -f .gitmodules ]; then
+                for mod_path in `grep "path =" .gitmodules | awk '{print $3}'`; do
+                        traverseModule "$mod_path" "$2"
+                done
+        fi
+	old_dir=$(echo $dir_path | cut -d':' -f1-1)
+	length_old_dir=`expr "$old_dir" : '.*'`
+	cd $old_dir
+	index=$(echo "$length_old_dir+2" | bc)
+	dir_path=`echo $dir_path $index | awk '{print substr($1, $2)}'`
+}
+
+# Propagates or recurses over all the submodules at any 
+# depth with any git command, e.g. git-clone, git-status,
+# git-commit etc., with the arguments supplied exactly as
+# it would have been supplied to the command otherwise.
+# This actually starts the recursive propagation
+propagate() {
+	project_home=`pwd`
+	echo Project Home: $project_home
+	if [ -d $project_home/.git/ ]; then
+		git_command=$1
+		shift
+		command_arguments=""
+		for arg in "$@"; do
+			if [ `expr index "$arg" ' '` -gt 0 ]; then
+				arg="\"$arg\""
+			fi 
+			command_arguments="$command_arguments $arg"
+		done
+		if [ $recurse_verbose -eq 1 ]; then
+			echo GIT Command git-$git_command with arguments\($#\) "$command_arguments"
+		fi
+		main_command="git-$git_command $command_arguments"
+		eval $main_command
+		if [ -f .gitmodules ]; then
+			for mod_path in `grep "path =" .gitmodules | awk '{print $3}'`; do
+				traverseModule $mod_path "$main_command"
+			done
+		fi
+	else
+		echo $project_home not a git repo thus exiting
+		exit
+	fi
+}
+
+recurse_verbose=0
 while test $# != 0
 do
 	case "$1" in
@@ -286,6 +359,17 @@ do
 	-*)
 		usage
 		;;
+	recurse)
+		recurse=1
+		case "$2" in
+			-v)
+				recurse_verbose=1
+				shift
+				;;
+		esac
+		shift
+		break
+		;;
 	*)
 		break
 		;;
@@ -303,17 +387,21 @@ case "$add,$branch" in
 	;;
 esac
 
-case "$add,$init,$update,$status,$cached" in
-1,,,,)
+
+case "$add,$init,$update,$recurse,$status,$cached" in
+1,,,,,)
 	module_add "$@"
 	;;
-,1,,,)
+,1,,,,)
 	modules_init "$@"
 	;;
-,,1,,)
+,,1,,,)
 	modules_update "$@"
 	;;
-,,,*,*)
+,,,1,,)
+	propagate "$@"
+	;;
+,,,,*,*)
 	modules_list "$@"
 	;;
 *)

[-- Attachment #3: git-submodule --]
[-- Type: application/octet-stream, Size: 8787 bytes --]

#!/bin/sh
#
# git-submodules.sh: add, init, update or list git submodules
# or recurse any git command over the submodules recursively.
#
# Copyright (c) 2007 Lars Hjemli

USAGE='[[--quiet] [--cached] [add <repo> [-b branch]|status|init|update] [--] [<path>...]|[recurse [-v] command arguments ...]]'
. git-sh-setup
require_work_tree

add=
branch=
init=
update=
status=
quiet=
cached=

#
# print stuff on stdout unless -q was specified
#
say()
{
	if test -z "$quiet"
	then
		echo "$@"
	fi
}

# NEEDSWORK: identical function exists in get_repo_base in clone.sh
get_repo_base() {
	(
		cd "`/bin/pwd`" &&
		cd "$1" || cd "$1.git" &&
		{
			cd .git
			pwd
		}
	) 2>/dev/null
}

#
# Map submodule path to submodule name
#
# $1 = path
#
module_name()
{
	# Do we have "submodule.<something>.path = $1" defined in .gitmodules file?
	re=$(printf '%s' "$1" | sed -e 's/[].[^$\\*]/\\&/g')
	name=$( GIT_CONFIG=.gitmodules \
		git config --get-regexp '^submodule\..*\.path$' |
		sed -n -e 's|^submodule\.\(.*\)\.path '"$re"'$|\1|p' )
       test -z "$name" &&
       die "No submodule mapping found in .gitmodules for path '$path'"
       echo "$name"
}

#
# Clone a submodule
#
# Prior to calling, modules_update checks that a possibly existing
# path is not a git repository.
# Likewise, module_add checks that path does not exist at all,
# since it is the location of a new submodule.
#
module_clone()
{
	path=$1
	url=$2

	# If there already is a directory at the submodule path,
	# expect it to be empty (since that is the default checkout
	# action) and try to remove it.
	# Note: if $path is a symlink to a directory the test will
	# succeed but the rmdir will fail. We might want to fix this.
	if test -d "$path"
	then
		rmdir "$path" 2>/dev/null ||
		die "Directory '$path' exist, but is neither empty nor a git repository"
	fi

	test -e "$path" &&
	die "A file already exist at path '$path'"

	git-clone -n "$url" "$path" ||
	die "Clone of '$url' into submodule path '$path' failed"
}

#
# Add a new submodule to the working tree, .gitmodules and the index
#
# $@ = repo [path]
#
# optional branch is stored in global branch variable
#
module_add()
{
	repo=$1
	path=$2

	if test -z "$repo"; then
		usage
	fi

	# Turn the source into an absolute path if
	# it is local
	if base=$(get_repo_base "$repo"); then
		repo="$base"
	fi

	# Guess path from repo if not specified or strip trailing slashes
	if test -z "$path"; then
		path=$(echo "$repo" | sed -e 's|/*$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g')
	else
		path=$(echo "$path" | sed -e 's|/*$||')
	fi

	test -e "$path" &&
	die "'$path' already exists"

	git ls-files --error-unmatch "$path" > /dev/null 2>&1 &&
	die "'$path' already exists in the index"

	module_clone "$path" "$repo" || exit
	(unset GIT_DIR && cd "$path" && git checkout -q ${branch:+-b "$branch" "origin/$branch"}) ||
	die "Unable to checkout submodule '$path'"
	git add "$path" ||
	die "Failed to add submodule '$path'"

	GIT_CONFIG=.gitmodules git config submodule."$path".path "$path" &&
	GIT_CONFIG=.gitmodules git config submodule."$path".url "$repo" &&
	git add .gitmodules ||
	die "Failed to register submodule '$path'"
}

#
# Register submodules in .git/config
#
# $@ = requested paths (default to all)
#
modules_init()
{
	git ls-files --stage -- "$@" | grep -e '^160000 ' |
	while read mode sha1 stage path
	do
		# Skip already registered paths
		name=$(module_name "$path") || exit
		url=$(git config submodule."$name".url)
		test -z "$url" || continue

		url=$(GIT_CONFIG=.gitmodules git config submodule."$name".url)
		test -z "$url" &&
		die "No url found for submodule path '$path' in .gitmodules"

		git config submodule."$name".url "$url" ||
		die "Failed to register url for submodule path '$path'"

		say "Submodule '$name' ($url) registered for path '$path'"
	done
}

#
# Update each submodule path to correct revision, using clone and checkout as needed
#
# $@ = requested paths (default to all)
#
modules_update()
{
	git ls-files --stage -- "$@" | grep -e '^160000 ' |
	while read mode sha1 stage path
	do
		name=$(module_name "$path") || exit
		url=$(git config submodule."$name".url)
		if test -z "$url"
		then
			# Only mention uninitialized submodules when its
			# path have been specified
			test "$#" != "0" &&
			say "Submodule path '$path' not initialized"
			continue
		fi

		if ! test -d "$path"/.git
		then
			module_clone "$path" "$url" || exit
			subsha1=
		else
			subsha1=$(unset GIT_DIR && cd "$path" &&
				git rev-parse --verify HEAD) ||
			die "Unable to find current revision in submodule path '$path'"
		fi

		if test "$subsha1" != "$sha1"
		then
			(unset GIT_DIR && cd "$path" && git-fetch &&
				git-checkout -q "$sha1") ||
			die "Unable to checkout '$sha1' in submodule path '$path'"

			say "Submodule path '$path': checked out '$sha1'"
		fi
	done
}

set_name_rev () {
	revname=$( (
		unset GIT_DIR &&
		cd "$1" && {
			git describe "$2" 2>/dev/null ||
			git describe --tags "$2" 2>/dev/null ||
			git describe --contains --tags "$2"
		}
	) )
	test -z "$revname" || revname=" ($revname)"
}

#
# List all submodules, prefixed with:
#  - submodule not initialized
#  + different revision checked out
#
# If --cached was specified the revision in the index will be printed
# instead of the currently checked out revision.
#
# $@ = requested paths (default to all)
#
modules_list()
{
	git ls-files --stage -- "$@" | grep -e '^160000 ' |
	while read mode sha1 stage path
	do
		name=$(module_name "$path") || exit
		url=$(git config submodule."$name".url)
		if test -z "url" || ! test -d "$path"/.git
		then
			say "-$sha1 $path"
			continue;
		fi
		set_name_rev "$path" "$sha1"
		if git diff-files --quiet -- "$path"
		then
			say " $sha1 $path$revname"
		else
			if test -z "$cached"
			then
				sha1=$(unset GIT_DIR && cd "$path" && git rev-parse --verify HEAD)
				set_name_rev "$path" "$sha1"
			fi
			say "+$sha1 $path$revname"
		fi
	done
}

# Simply checks whether the submodule is initialized
# or not. If not initialized it does so.
initializeSubModule() {
	if [ ! -d "$1"/.git ]; then
		if [ $recurse_verbose -eq 1 ]; then
			echo Initializing and updating "$1"
		fi
		git-submodule init "$1"; git-submodule update "$1"
	fi
}

# This actually traverses the module; checks
# whether the module is initialized or not.
# if not initialized, then done so and then the
# intended command is evaluated. Then it
# recursively goes into it modules.
traverseModule() {
	current_dir=`pwd`
	dir_path="$current_dir:$dir_path"
	initializeSubModule "$1"
        cd "$1"
	if [ $recurse_verbose -eq 1 ]; then
		echo Working in mod $1 @ `pwd` with $2
	fi
        eval "$2"
	if [ -f .gitmodules ]; then
                for mod_path in `grep "path =" .gitmodules | awk '{print $3}'`; do
                        traverseModule "$mod_path" "$2"
                done
        fi
	old_dir=$(echo $dir_path | cut -d':' -f1-1)
	length_old_dir=`expr "$old_dir" : '.*'`
	cd $old_dir
	index=$(echo "$length_old_dir+2" | bc)
	dir_path=`echo $dir_path $index | awk '{print substr($1, $2)}'`
}

# Propagates or recurses over all the submodules at any 
# depth with any git command, e.g. git-clone, git-status,
# git-commit etc., with the arguments supplied exactly as
# it would have been supplied to the command otherwise.
# This actually starts the recursive propagation
propagate() {
	project_home=`pwd`
	echo Project Home: $project_home
	if [ -d $project_home/.git/ ]; then
		git_command=$1
		shift
		command_arguments=""
		for arg in "$@"; do
			if [ `expr index "$arg" ' '` -gt 0 ]; then
				arg="\"$arg\""
			fi 
			command_arguments="$command_arguments $arg"
		done
		if [ $recurse_verbose -eq 1 ]; then
			echo GIT Command git-$git_command with arguments\($#\) "$command_arguments"
		fi
		main_command="git-$git_command $command_arguments"
		eval $main_command
		if [ -f .gitmodules ]; then
			for mod_path in `grep "path =" .gitmodules | awk '{print $3}'`; do
				traverseModule $mod_path "$main_command"
			done
		fi
	else
		echo $project_home not a git repo thus exiting
		exit
	fi
}

recurse_verbose=0
while test $# != 0
do
	case "$1" in
	add)
		add=1
		;;
	init)
		init=1
		;;
	update)
		update=1
		;;
	status)
		status=1
		;;
	-q|--quiet)
		quiet=1
		;;
	-b|--branch)
		case "$2" in
		'')
			usage
			;;
		esac
		branch="$2"; shift
		;;
	--cached)
		cached=1
		;;
	--)
		break
		;;
	-*)
		usage
		;;
	recurse)
		recurse=1
		case "$2" in
			-v)
				recurse_verbose=1
				shift
				;;
		esac
		shift
		break
		;;
	*)
		break
		;;
	esac
	shift
done

case "$add,$branch" in
1,*)
	;;
,)
	;;
,*)
	usage
	;;
esac


case "$add,$init,$update,$recurse,$status,$cached" in
1,,,,,)
	module_add "$@"
	;;
,1,,,,)
	modules_init "$@"
	;;
,,1,,,)
	modules_update "$@"
	;;
,,,1,,)
	propagate "$@"
	;;
,,,,*,*)
	modules_list "$@"
	;;
*)
	usage
	;;
esac

^ permalink raw reply related

* [PATCH] Added initialize and update support for submodule in git clone
From: Imran M Yousuf @ 2008-01-08  3:22 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 3917 bytes --]

This patch adds support for initializing and updating submodules when
a repo is cloned. The advantage it adds is, the user actually does not
have to know whether it has a module or not and if it does to what
depth and path. For this I added a option -w or --with-submodule for
initializing and updating during clone stage.

I am working on project that has multiple maven modules and some of
the modules have separate GIT repo and needs to be linked with the
main project after maturity; we wanted that when developers clone the
main repo it should fetch all the submodules at once.

Following is the diff with git-clone 1.5.3.7; I also attached the diff
and modified file in the attachment. I would like to add that I am not
fully sure about unsetting the GIT_DIR, GIT_CONFIG and GIT_WORK_TREE
and resetting them and thus added them to the comment. If there is a
better way to achieve it I would gratefully incorporate it.

diff --git a/git-clone b/git-clone
index 204a769..63510c4 100755
--- a/git-clone
+++ b/git-clone
@@ -14,7 +14,7 @@ die() {
 }

 usage() {
-	die "Usage: $0 [--template=<template_directory>] [--reference
<reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--origin
<name>] [--depth <n>] [-n] <repo> [<dir>]"
+	die "Usage: $0 [--template=<template_directory>] [--reference
<reference-repo>] [--bare] [-l [-s]] [-q] [-w|--with-submodule] [-u
<upload-pack>] [--origin <name>] [--depth <n>] [-n] <repo> [<dir>]"
 }

 get_repo_base() {
@@ -90,6 +90,29 @@ Perhaps git-update-server-info needs to be run there?"
 	fi
 }

+initializeSubModule() {
+	if [ ! -d "$1"/.git ]; then
+		git-submodule-test init "$1"; git-submodule-test update "$1"
+	fi
+}
+
+initSubModules() {
+	current_dir=`pwd`
+	dir_path="$current_dir:$dir_path"
+	initializeSubModule "$1"
+        cd "$1"
+	if [ -f .gitmodules ]; then
+                for sub_mod_path in `grep "path =" .gitmodules | awk
'{print $3}'`; do
+			initSubModules "$sub_mod_path"
+                done
+        fi
+	old_dir=$(echo $dir_path | cut -d':' -f1-1)
+	length_old_dir=`expr "$old_dir" : '.*'`
+	cd $old_dir
+	index=$(echo "$length_old_dir+2" | bc)
+	dir_path=`echo $dir_path $index | awk '{print substr($1, $2)}'`
+}
+
 quiet=
 local=no
 use_local_hardlink=yes
@@ -106,6 +129,7 @@ depth=
 no_progress=
 local_explicitly_asked_for=
 test -t 1 || no_progress=--no-progress
+with_submodule=0
 while
 	case "$#,$1" in
 	0,*) break ;;
@@ -156,6 +180,7 @@ while
 		upload_pack="--upload-pack=$1" ;;
 	*,--upload-pack=*)
 		upload_pack=--upload-pack=$(expr "z$1" : 'z-[^=]*=\(.*\)') ;;
+	*,-w|*,--w|*,--wi|*,--wit|*,--with|*,--with-s|*,--with-su|*,--with-sub|*,--with-subm|*,--with-submo|*,--with-submod|*,--with-submodu|*,--with-submodul|*,--with-submodule)
with_submodule=1 ;;
 	1,--depth) usage;;
 	*,--depth)
 		shift
@@ -465,4 +490,38 @@ then
 fi
 rm -f "$GIT_DIR/CLONE_HEAD" "$GIT_DIR/REMOTE_HEAD"

+# The following section initializes the submodules of the repo
+if [ $with_submodule -eq 1  ]; then
+	if [ -f .gitmodules ]; then
+
+		# Need to know either what is the alternate
+		# or what else to backup and unset
+		# If this is not done in that case recursion
+		# in a subdirectory of the top level fails
+		# Thus the old values are backed up and restored
+		# after recursion
+		OLD_GIT_DIR="$GIT_DIR"
+		OLD_GIT_CONFIG="$GIT_CONFIG"
+		OLD_GIT_WORK_TREE="$GIT_WORK_TREE"
+		unset GIT_DIR
+		unset GIT_CONFIG
+		unset GIT_WORK_TREE
+
+		# The following loop iterates over the submodules
+		# visible from he top of the module
+	        for mod_path in `grep "path =" .gitmodules | awk '{print $3}'`; do
+                        initSubModules "$mod_path"
+                done
+
+		GIT_DIR="$OLD_GIT_DIR"
+		GIT_CONFIG="$OLD_GIT_CONFIG"
+		GIT_WORK_TREE="$OLD_GIT_WORK_TREE"
+
+		# The following export is probably not required
+		export GIT_DIR
+		export GIT_CONFIG
+		export GIT_WORK_TREE
+	fi
+fi
+
 trap - 0

-- 
Imran M Yousuf

[-- Attachment #2: git-clone --]
[-- Type: application/octet-stream, Size: 13388 bytes --]

#!/bin/sh
#
# Copyright (c) 2005, Linus Torvalds
# Copyright (c) 2005, Junio C Hamano
#
# Clone a repository into a different directory that does not yet exist.

# See git-sh-setup why.
unset CDPATH

die() {
	echo >&2 "$@"
	exit 1
}

usage() {
	die "Usage: $0 [--template=<template_directory>] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-w|--with-submodule] [-u <upload-pack>] [--origin <name>] [--depth <n>] [-n] <repo> [<dir>]"
}

get_repo_base() {
	(
		cd "`/bin/pwd`" &&
		cd "$1" || cd "$1.git" &&
		{
			cd .git
			pwd
		}
	) 2>/dev/null
}

if [ -n "$GIT_SSL_NO_VERIFY" -o \
	"`git config --bool http.sslVerify`" = false ]; then
    curl_extra_args="-k"
fi

http_fetch () {
	# $1 = Remote, $2 = Local
	curl -nsfL $curl_extra_args "$1" >"$2" ||
		case $? in
		126|127) exit ;;
		*)	 return $? ;;
		esac
}

clone_dumb_http () {
	# $1 - remote, $2 - local
	cd "$2" &&
	clone_tmp="$GIT_DIR/clone-tmp" &&
	mkdir -p "$clone_tmp" || exit 1
	if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \
		"`git config --bool http.noEPSV`" = true ]; then
		curl_extra_args="${curl_extra_args} --disable-epsv"
	fi
	http_fetch "$1/info/refs" "$clone_tmp/refs" ||
		die "Cannot get remote repository information.
Perhaps git-update-server-info needs to be run there?"
	test "z$quiet" = z && v=-v || v=
	while read sha1 refname
	do
		name=`expr "z$refname" : 'zrefs/\(.*\)'` &&
		case "$name" in
		*^*)	continue;;
		esac
		case "$bare,$name" in
		yes,* | ,heads/* | ,tags/*) ;;
		*)	continue ;;
		esac
		if test -n "$use_separate_remote" &&
		   branch_name=`expr "z$name" : 'zheads/\(.*\)'`
		then
			tname="remotes/$origin/$branch_name"
		else
			tname=$name
		fi
		git-http-fetch $v -a -w "$tname" "$sha1" "$1" || exit 1
	done <"$clone_tmp/refs"
	rm -fr "$clone_tmp"
	http_fetch "$1/HEAD" "$GIT_DIR/REMOTE_HEAD" ||
	rm -f "$GIT_DIR/REMOTE_HEAD"
	if test -f "$GIT_DIR/REMOTE_HEAD"; then
		head_sha1=`cat "$GIT_DIR/REMOTE_HEAD"`
		case "$head_sha1" in
		'ref: refs/'*)
			;;
		*)
			git-http-fetch $v -a "$head_sha1" "$1" ||
			rm -f "$GIT_DIR/REMOTE_HEAD"
			;;
		esac
	fi
}

initializeSubModule() {
	if [ ! -d "$1"/.git ]; then
		git-submodule-test init "$1"; git-submodule-test update "$1"
	fi
}

initSubModules() {
	current_dir=`pwd`
	dir_path="$current_dir:$dir_path"
	initializeSubModule "$1"
        cd "$1"
	if [ -f .gitmodules ]; then
                for sub_mod_path in `grep "path =" .gitmodules | awk '{print $3}'`; do
			initSubModules "$sub_mod_path"
                done
        fi
	old_dir=$(echo $dir_path | cut -d':' -f1-1)
	length_old_dir=`expr "$old_dir" : '.*'`
	cd $old_dir
	index=$(echo "$length_old_dir+2" | bc)
	dir_path=`echo $dir_path $index | awk '{print substr($1, $2)}'`
}

quiet=
local=no
use_local_hardlink=yes
local_shared=no
unset template
no_checkout=
upload_pack=
bare=
reference=
origin=
origin_override=
use_separate_remote=t
depth=
no_progress=
local_explicitly_asked_for=
test -t 1 || no_progress=--no-progress
with_submodule=0
while
	case "$#,$1" in
	0,*) break ;;
	*,-n|*,--no|*,--no-|*,--no-c|*,--no-ch|*,--no-che|*,--no-chec|\
	*,--no-check|*,--no-checko|*,--no-checkou|*,--no-checkout)
	  no_checkout=yes ;;
	*,--na|*,--nak|*,--nake|*,--naked|\
	*,-b|*,--b|*,--ba|*,--bar|*,--bare) bare=yes ;;
	*,-l|*,--l|*,--lo|*,--loc|*,--loca|*,--local)
	  local_explicitly_asked_for=yes
	  use_local_hardlink=yes ;;
	*,--no-h|*,--no-ha|*,--no-har|*,--no-hard|*,--no-hardl|\
	*,--no-hardli|*,--no-hardlin|*,--no-hardlink|*,--no-hardlinks)
	  use_local_hardlink=no ;;
        *,-s|*,--s|*,--sh|*,--sha|*,--shar|*,--share|*,--shared)
          local_shared=yes; ;;
	1,--template) usage ;;
	*,--template)
		shift; template="--template=$1" ;;
	*,--template=*)
	  template="$1" ;;
	*,-q|*,--quiet) quiet=-q ;;
	*,--use-separate-remote) ;;
	*,--no-separate-remote)
		die "clones are always made with separate-remote layout" ;;
	1,--reference) usage ;;
	*,--reference)
		shift; reference="$1" ;;
	*,--reference=*)
		reference=`expr "z$1" : 'z--reference=\(.*\)'` ;;
	*,-o|*,--or|*,--ori|*,--orig|*,--origi|*,--origin)
		case "$2" in
		'')
		    usage ;;
		*/*)
		    die "'$2' is not suitable for an origin name"
		esac
		git check-ref-format "heads/$2" ||
		    die "'$2' is not suitable for a branch name"
		test -z "$origin_override" ||
		    die "Do not give more than one --origin options."
		origin_override=yes
		origin="$2"; shift
		;;
	1,-u|1,--upload-pack) usage ;;
	*,-u|*,--upload-pack)
		shift
		upload_pack="--upload-pack=$1" ;;
	*,--upload-pack=*)
		upload_pack=--upload-pack=$(expr "z$1" : 'z-[^=]*=\(.*\)') ;;
	*,-w|*,--w|*,--wi|*,--wit|*,--with|*,--with-s|*,--with-su|*,--with-sub|*,--with-subm|*,--with-submo|*,--with-submod|*,--with-submodu|*,--with-submodul|*,--with-submodule) with_submodule=1 ;;
	1,--depth) usage;;
	*,--depth)
		shift
		depth="--depth=$1";;
	*,-*) usage ;;
	*) break ;;
	esac
do
	shift
done

repo="$1"
test -n "$repo" ||
    die 'you must specify a repository to clone.'

# --bare implies --no-checkout and --no-separate-remote
if test yes = "$bare"
then
	if test yes = "$origin_override"
	then
		die '--bare and --origin $origin options are incompatible.'
	fi
	no_checkout=yes
	use_separate_remote=
fi

if test -z "$origin"
then
	origin=origin
fi

# Turn the source into an absolute path if
# it is local
if base=$(get_repo_base "$repo"); then
	repo="$base"
	local=yes
fi

dir="$2"
# Try using "humanish" part of source repo if user didn't specify one
[ -z "$dir" ] && dir=$(echo "$repo" | sed -e 's|/$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g')
[ -e "$dir" ] && die "destination directory '$dir' already exists."
[ yes = "$bare" ] && unset GIT_WORK_TREE
[ -n "$GIT_WORK_TREE" ] && [ -e "$GIT_WORK_TREE" ] &&
die "working tree '$GIT_WORK_TREE' already exists."
D=
W=
cleanup() {
	err=$?
	test -z "$D" && rm -rf "$dir"
	test -z "$W" && test -n "$GIT_WORK_TREE" && rm -rf "$GIT_WORK_TREE"
	cd ..
	test -n "$D" && rm -rf "$D"
	test -n "$W" && rm -rf "$W"
	exit $err
}
trap cleanup 0
mkdir -p "$dir" && D=$(cd "$dir" && pwd) || usage
test -n "$GIT_WORK_TREE" && mkdir -p "$GIT_WORK_TREE" &&
W=$(cd "$GIT_WORK_TREE" && pwd) && export GIT_WORK_TREE="$W"
if test yes = "$bare" || test -n "$GIT_WORK_TREE"; then
	GIT_DIR="$D"
else
	GIT_DIR="$D/.git"
fi &&
export GIT_DIR &&
GIT_CONFIG="$GIT_DIR/config" git-init $quiet ${template+"$template"} || usage

if test -n "$bare"
then
	GIT_CONFIG="$GIT_DIR/config" git config core.bare true
fi

if test -n "$reference"
then
	ref_git=
	if test -d "$reference"
	then
		if test -d "$reference/.git/objects"
		then
			ref_git="$reference/.git"
		elif test -d "$reference/objects"
		then
			ref_git="$reference"
		fi
	fi
	if test -n "$ref_git"
	then
		ref_git=$(cd "$ref_git" && pwd)
		echo "$ref_git/objects" >"$GIT_DIR/objects/info/alternates"
		(
			GIT_DIR="$ref_git" git for-each-ref \
				--format='%(objectname) %(*objectname)'
		) |
		while read a b
		do
			test -z "$a" ||
			git update-ref "refs/reference-tmp/$a" "$a"
			test -z "$b" ||
			git update-ref "refs/reference-tmp/$b" "$b"
		done
	else
		die "reference repository '$reference' is not a local directory."
	fi
fi

rm -f "$GIT_DIR/CLONE_HEAD"

# We do local magic only when the user tells us to.
case "$local" in
yes)
	( cd "$repo/objects" ) ||
		die "cannot chdir to local '$repo/objects'."

	if test "$local_shared" = yes
	then
		mkdir -p "$GIT_DIR/objects/info"
		echo "$repo/objects" >>"$GIT_DIR/objects/info/alternates"
	else
		l= &&
		if test "$use_local_hardlink" = yes
		then
			# See if we can hardlink and drop "l" if not.
			sample_file=$(cd "$repo" && \
				      find objects -type f -print | sed -e 1q)
			# objects directory should not be empty because
			# we are cloning!
			test -f "$repo/$sample_file" || exit
			if ln "$repo/$sample_file" "$GIT_DIR/objects/sample" 2>/dev/null
			then
				rm -f "$GIT_DIR/objects/sample"
				l=l
			elif test -n "$local_explicitly_asked_for"
			then
				echo >&2 "Warning: -l asked but cannot hardlink to $repo"
			fi
		fi &&
		cd "$repo" &&
		find objects -depth -print | cpio -pumd$l "$GIT_DIR/" || exit 1
	fi
	git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1
	;;
*)
	case "$repo" in
	rsync://*)
		case "$depth" in
		"") ;;
		*) die "shallow over rsync not supported" ;;
		esac
		rsync $quiet -av --ignore-existing  \
			--exclude info "$repo/objects/" "$GIT_DIR/objects/" ||
		exit
		# Look at objects/info/alternates for rsync -- http will
		# support it natively and git native ones will do it on the
		# remote end.  Not having that file is not a crime.
		rsync -q "$repo/objects/info/alternates" \
			"$GIT_DIR/TMP_ALT" 2>/dev/null ||
			rm -f "$GIT_DIR/TMP_ALT"
		if test -f "$GIT_DIR/TMP_ALT"
		then
		    ( cd "$D" &&
		      . git-parse-remote &&
		      resolve_alternates "$repo" <"$GIT_DIR/TMP_ALT" ) |
		    while read alt
		    do
			case "$alt" in 'bad alternate: '*) die "$alt";; esac
			case "$quiet" in
			'')	echo >&2 "Getting alternate: $alt" ;;
			esac
			rsync $quiet -av --ignore-existing  \
			    --exclude info "$alt" "$GIT_DIR/objects" || exit
		    done
		    rm -f "$GIT_DIR/TMP_ALT"
		fi
		git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1
		;;
	https://*|http://*|ftp://*)
		case "$depth" in
		"") ;;
		*) die "shallow over http or ftp not supported" ;;
		esac
		if test -z ""
		then
			clone_dumb_http "$repo" "$D"
		else
			die "http transport not supported, rebuild Git with curl support"
		fi
		;;
	*)
		case "$upload_pack" in
		'') git-fetch-pack --all -k $quiet $depth $no_progress "$repo";;
		*) git-fetch-pack --all -k $quiet "$upload_pack" $depth $no_progress "$repo" ;;
		esac >"$GIT_DIR/CLONE_HEAD" ||
			die "fetch-pack from '$repo' failed."
		;;
	esac
	;;
esac
test -d "$GIT_DIR/refs/reference-tmp" && rm -fr "$GIT_DIR/refs/reference-tmp"

if test -f "$GIT_DIR/CLONE_HEAD"
then
	# Read git-fetch-pack -k output and store the remote branches.
	if [ -n "$use_separate_remote" ]
	then
		branch_top="remotes/$origin"
	else
		branch_top="heads"
	fi
	tag_top="tags"
	while read sha1 name
	do
		case "$name" in
		*'^{}')
			continue ;;
		HEAD)
			destname="REMOTE_HEAD" ;;
		refs/heads/*)
			destname="refs/$branch_top/${name#refs/heads/}" ;;
		refs/tags/*)
			destname="refs/$tag_top/${name#refs/tags/}" ;;
		*)
			continue ;;
		esac
		git update-ref -m "clone: from $repo" "$destname" "$sha1" ""
	done < "$GIT_DIR/CLONE_HEAD"
fi

if test -n "$W"; then
	cd "$W" || exit
else
	cd "$D" || exit
fi

if test -z "$bare" && test -f "$GIT_DIR/REMOTE_HEAD"
then
	# a non-bare repository is always in separate-remote layout
	remote_top="refs/remotes/$origin"
	head_sha1=`cat "$GIT_DIR/REMOTE_HEAD"`
	case "$head_sha1" in
	'ref: refs/'*)
		# Uh-oh, the remote told us (http transport done against
		# new style repository with a symref HEAD).
		# Ideally we should skip the guesswork but for now
		# opt for minimum change.
		head_sha1=`expr "z$head_sha1" : 'zref: refs/heads/\(.*\)'`
		head_sha1=`cat "$GIT_DIR/$remote_top/$head_sha1"`
		;;
	esac

	# The name under $remote_top the remote HEAD seems to point at.
	head_points_at=$(
		(
			test -f "$GIT_DIR/$remote_top/master" && echo "master"
			cd "$GIT_DIR/$remote_top" &&
			find . -type f -print | sed -e 's/^\.\///'
		) | (
		done=f
		while read name
		do
			test t = $done && continue
			branch_tip=`cat "$GIT_DIR/$remote_top/$name"`
			if test "$head_sha1" = "$branch_tip"
			then
				echo "$name"
				done=t
			fi
		done
		)
	)

	# Upstream URL
	git config remote."$origin".url "$repo" &&

	# Set up the mappings to track the remote branches.
	git config remote."$origin".fetch \
		"+refs/heads/*:$remote_top/*" '^$' &&

	# Write out remote.$origin config, and update our "$head_points_at".
	case "$head_points_at" in
	?*)
		# Local default branch
		git symbolic-ref HEAD "refs/heads/$head_points_at" &&

		# Tracking branch for the primary branch at the remote.
		git update-ref HEAD "$head_sha1" &&

		rm -f "refs/remotes/$origin/HEAD"
		git symbolic-ref "refs/remotes/$origin/HEAD" \
			"refs/remotes/$origin/$head_points_at" &&

		git config branch."$head_points_at".remote "$origin" &&
		git config branch."$head_points_at".merge "refs/heads/$head_points_at"
		;;
	'')
		# Source had detached HEAD pointing nowhere
		git update-ref --no-deref HEAD "$head_sha1" &&
		rm -f "refs/remotes/$origin/HEAD"
		;;
	esac

	case "$no_checkout" in
	'')
		test "z$quiet" = z -a "z$no_progress" = z && v=-v || v=
		git read-tree -m -u $v HEAD HEAD
	esac
fi
rm -f "$GIT_DIR/CLONE_HEAD" "$GIT_DIR/REMOTE_HEAD"

# The following section initializes the submodules of the repo
if [ $with_submodule -eq 1  ]; then
	if [ -f .gitmodules ]; then

		# Need to know either what is the alternate 
		# or what else to backup and unset
		# If this is not done in that case recursion 
		# in a subdirectory of the top level fails
		# Thus the old values are backed up and restored
		# after recursion
		OLD_GIT_DIR="$GIT_DIR"
		OLD_GIT_CONFIG="$GIT_CONFIG"
		OLD_GIT_WORK_TREE="$GIT_WORK_TREE"
		unset GIT_DIR
		unset GIT_CONFIG
		unset GIT_WORK_TREE

		# The following loop iterates over the submodules
		# visible from he top of the module
	        for mod_path in `grep "path =" .gitmodules | awk '{print $3}'`; do
                        initSubModules "$mod_path"
                done

		GIT_DIR="$OLD_GIT_DIR"
		GIT_CONFIG="$OLD_GIT_CONFIG"
		GIT_WORK_TREE="$OLD_GIT_WORK_TREE"

		# The following export is probably not required
		export GIT_DIR
		export GIT_CONFIG
		export GIT_WORK_TREE
	fi
fi

trap - 0

[-- Attachment #3: git-clone-diff-1.5.3.7.txt --]
[-- Type: text/plain, Size: 2978 bytes --]

diff --git a/git-clone b/git-clone
index 204a769..63510c4 100755
--- a/git-clone
+++ b/git-clone
@@ -14,7 +14,7 @@ die() {
 }
 
 usage() {
-	die "Usage: $0 [--template=<template_directory>] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--origin <name>] [--depth <n>] [-n] <repo> [<dir>]"
+	die "Usage: $0 [--template=<template_directory>] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-w|--with-submodule] [-u <upload-pack>] [--origin <name>] [--depth <n>] [-n] <repo> [<dir>]"
 }
 
 get_repo_base() {
@@ -90,6 +90,29 @@ Perhaps git-update-server-info needs to be run there?"
 	fi
 }
 
+initializeSubModule() {
+	if [ ! -d "$1"/.git ]; then
+		git-submodule-test init "$1"; git-submodule-test update "$1"
+	fi
+}
+
+initSubModules() {
+	current_dir=`pwd`
+	dir_path="$current_dir:$dir_path"
+	initializeSubModule "$1"
+        cd "$1"
+	if [ -f .gitmodules ]; then
+                for sub_mod_path in `grep "path =" .gitmodules | awk '{print $3}'`; do
+			initSubModules "$sub_mod_path"
+                done
+        fi
+	old_dir=$(echo $dir_path | cut -d':' -f1-1)
+	length_old_dir=`expr "$old_dir" : '.*'`
+	cd $old_dir
+	index=$(echo "$length_old_dir+2" | bc)
+	dir_path=`echo $dir_path $index | awk '{print substr($1, $2)}'`
+}
+
 quiet=
 local=no
 use_local_hardlink=yes
@@ -106,6 +129,7 @@ depth=
 no_progress=
 local_explicitly_asked_for=
 test -t 1 || no_progress=--no-progress
+with_submodule=0
 while
 	case "$#,$1" in
 	0,*) break ;;
@@ -156,6 +180,7 @@ while
 		upload_pack="--upload-pack=$1" ;;
 	*,--upload-pack=*)
 		upload_pack=--upload-pack=$(expr "z$1" : 'z-[^=]*=\(.*\)') ;;
+	*,-w|*,--w|*,--wi|*,--wit|*,--with|*,--with-s|*,--with-su|*,--with-sub|*,--with-subm|*,--with-submo|*,--with-submod|*,--with-submodu|*,--with-submodul|*,--with-submodule) with_submodule=1 ;;
 	1,--depth) usage;;
 	*,--depth)
 		shift
@@ -465,4 +490,38 @@ then
 fi
 rm -f "$GIT_DIR/CLONE_HEAD" "$GIT_DIR/REMOTE_HEAD"
 
+# The following section initializes the submodules of the repo
+if [ $with_submodule -eq 1  ]; then
+	if [ -f .gitmodules ]; then
+
+		# Need to know either what is the alternate 
+		# or what else to backup and unset
+		# If this is not done in that case recursion 
+		# in a subdirectory of the top level fails
+		# Thus the old values are backed up and restored
+		# after recursion
+		OLD_GIT_DIR="$GIT_DIR"
+		OLD_GIT_CONFIG="$GIT_CONFIG"
+		OLD_GIT_WORK_TREE="$GIT_WORK_TREE"
+		unset GIT_DIR
+		unset GIT_CONFIG
+		unset GIT_WORK_TREE
+
+		# The following loop iterates over the submodules
+		# visible from he top of the module
+	        for mod_path in `grep "path =" .gitmodules | awk '{print $3}'`; do
+                        initSubModules "$mod_path"
+                done
+
+		GIT_DIR="$OLD_GIT_DIR"
+		GIT_CONFIG="$OLD_GIT_CONFIG"
+		GIT_WORK_TREE="$OLD_GIT_WORK_TREE"
+
+		# The following export is probably not required
+		export GIT_DIR
+		export GIT_CONFIG
+		export GIT_WORK_TREE
+	fi
+fi
+
 trap - 0

^ permalink raw reply related

* [PATCH] Documentation: config: add 'help.*' and 'instaweb.*' variables.
From: Christian Couder @ 2008-01-08  3:55 UTC (permalink / raw)
  To: Junio Hamano; +Cc: git

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
 Documentation/config.txt |   33 +++++++++++++++++++++++++++++++++
 1 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index e1eaee9..c9895dc 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -585,6 +585,15 @@ specified as 'gitcvs.<access_method>.<varname>' (where 'access_method'
 is one of "ext" and "pserver") to make them apply only for the given
 access method.
 
+help.browser::
+	Specify the browser that will be used to display help in the
+	'web' format. See gitlink:git-help[1].
+
+help.format::
+	Override the default help format used by gitlink:git-help[1].
+	Values 'man', 'info', 'web' and 'html' are supported. 'man' is
+	the default. 'web' and 'html' are the same.
+
 http.proxy::
 	Override the HTTP proxy, normally configured using the 'http_proxy'
 	environment variable (see gitlink:curl[1]).  This can be overridden
@@ -642,6 +651,25 @@ i18n.logOutputEncoding::
 	Character encoding the commit messages are converted to when
 	running `git-log` and friends.
 
+instaweb.browser::
+	Specify the program that will be used to browse your working
+	repository in gitweb. See gitlink:git-instaweb[1].
+
+instaweb.httpd::
+	The HTTP daemon command-line to start gitweb on your working
+	repository. See gitlink:git-instaweb[1].
+
+instaweb.local::
+	If true the web server started by gitlink:git-instaweb[1] will
+	be bound to the local IP (127.0.0.1).
+
+instaweb.modulepath::
+	The module path for an apache httpd used by gitlink:git-instaweb[1].
+
+instaweb.port::
+	The port number to bind the gitweb httpd to. See
+	gitlink:git-instaweb[1].
+
 log.showroot::
 	If true, the initial commit will be shown as a big creation event.
 	This is equivalent to a diff against an empty tree.
@@ -843,4 +871,8 @@ receive.denyNonFastForwards::
 transfer.unpackLimit::
 	When `fetch.unpackLimit` or `receive.unpackLimit` are
 	not set, the value of this variable is used instead.
+
+web.browser::
+	Specify a web browser that may be used by some commands.
+	Currently only gitlink:git-instaweb[1] and gitlink:git-help[1]
+	may use it.
-- 
1.5.4.rc2.38.gd6da3

^ permalink raw reply related

* Re: [RFC] Initializing and updating submodules during clone and recursion over submodules
From: Miklos Vajna @ 2008-01-08  4:07 UTC (permalink / raw)
  To: Imran M Yousuf; +Cc: git
In-Reply-To: <7bfdc29a0801061827k7bb18017k17f0e1ae5fff0873@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 445 bytes --]

On Mon, Jan 07, 2008 at 08:27:25AM +0600, Imran M Yousuf <imyousuf@gmail.com> wrote:
> I have added "recurse" command to the git-submodule to recurse any git
> command and also added fetching of submodules during cloning. Please
> have a look at the changes and let me know your comments on them.

you want to send a patch. please read Documentation/SubmittingPatches. i
doubt anybody will comment your work unless you do so.

thanks,
- VMiklos

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [PATCH] git-gui: translate most (if not all) of the messages in zh_cn.po to chinese
From: Xudong Guan @ 2008-01-08  4:49 UTC (permalink / raw)
  To: eric miao; +Cc: git
In-Reply-To: <f17812d70801061734y6fcbe556i3ecee06b375c4971@mail.gmail.com>

On 09:34(+0800) Mon 07 Jan, eric miao wrote:
> [ as potential character encoding mess of some mailer to utf-8, the
> patch is also attached ]

Excellent translations! Many thanks,

Xudong

^ permalink raw reply

* Re: how to use git merge -s subtree?
From: Sean @ 2008-01-08  5:34 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: David Soria Parra, git
In-Reply-To: <7vlk71z6sd.fsf@gitster.siamese.dyndns.org>

On Mon, 07 Jan 2008 13:04:34 -0800
Junio C Hamano <gitster@pobox.com> wrote:

> That's asking for the history of a _path_ (or subset defined by
> paths, as in "what changes were made to paths under 'arch/'"),
> which is very different from asking "I have B/foo.c -- show me
> the history of that _file_".
> 
> Remember, David stated:
> 
> >> ... So you cannot do git-log B/foo.c as git doesnot know where
> >> to search it as it thinks it is in /foo.c not in B/foo.c ...
> 
> Notice "as git does not know where to search it" part?
> 
> Think --- what does that "it" refer to in that sentence?
> 
> The statement is not about paths.  If it were about paths, then
> the output of "git log B/foo.c" does show what he wants.  The
> question "git log B/foo.c" asks is "what change were made to the
> path at B/foo.c".  The changes made to B/foo.c (i.e. what's
> shown with the diff headers that begin with "--- a/B/foo.c") are
> shown.  The changes made to foo.c are not shown.
> 
> But that is different from what David is asking.  He wants to
> know what changes were made to B/foo.c or to foo.c, and wants to
> make the choice between the two depend on commit.  The reason
> you think you can pick between foo.c and B/foo.c is because
> there is an illusion that somehow there is an i-node like file
> identity that is kept track of, and it is preserved across
> renames and merges.
> 
> That's keeping track of the history of a _file_.
> 
> And as you know, git doesn't do that.
> 
> What git does is to keep track of the history of the whole tree,
> but prune the parts that are not interesting away when you view
> the history.  And the pruning can be specified by _PATH_.
> 
> See the difference?
> 

Junio,

Thanks for taking the time to answer, I know you're busy with much more
pressing issues getting 1.5.4 out the door.  You make the distinction
between paths and files quite clear, and why it's important to keep in
mind.

In the case of the "--follow" option though, the user might be forgiven
for thinking in terms of files rather than paths.  Even the git-log
documentation says for "--follow", "Continue listing the history of a
file beyond renames".   Which at least implies that Git knows about
file history, rather than just paths.

It's reasonable for a user to expect "git log --follow B/foo.c" to do
The-Right-Thing in the subtree merge case.  But I recognize that it would
actually be rather difficult to implement, perhaps making it impractical.

Cheers,
Sean

^ permalink raw reply

* Re: [PATCH] Added recurse command to git submodule
From: Junio C Hamano @ 2008-01-08  5:44 UTC (permalink / raw)
  To: Imran M Yousuf; +Cc: git
In-Reply-To: <7bfdc29a0801071914s207be500veae8e507d7d9d29@mail.gmail.com>

"Imran M Yousuf" <imyousuf@gmail.com> writes:

> Following is the diff with git-submdoule version 1.5.3.7. I also
> attached the diff and the modified file in the attachment.

Please do not do this when the submission is for real (I think
you did not mean this for inclusion but for comment so it is Ok
this time around), as such a message cannot be processed with
our automated tools but need to be applied by hand.

Just send a non whitespace-corrupted, plain text patch.  A
corrupt text patch followed by an attachment is the worst of
both worlds.

> @@ -251,6 +252,78 @@ modules_list()
>  	done
>  }
>
> +# Simply checks whether the submodule is initialized
> +# or not. If not initialized it does so.
> +initializeSubModule() {
> +	if [ ! -d "$1"/.git ]; then
> +		if [ $recurse_verbose -eq 1 ]; then
> +			echo Initializing and updating "$1"
> +		fi
> +		git-submodule init "$1"; git-submodule update "$1"
> +	fi
> +}

The comment above sounds quite wrong, isn't it?  It is not just
"simply check" but actively makes sure it is initialized.

Do we use CamelCase in our shell script?

Making -r to always recurse _fully_ feels quite wrong.  It is
one thing to allow "git submodule init --recursive" to recurse
fully and initialize everything, but it is another thing to
force full instantiation of submodules that the user _chose_ not
to check out, when the user has checkout of some but not all
submodules and asks "git submodule update --recursive".

> +# This actually traverses the module; checks
> +# whether the module is initialized or not.
> +# if not initialized, then done so and then the
> +# intended command is evaluated. Then it
> +# recursively goes into it modules.
> +traverseModule() {
> +	current_dir=`pwd`
> +	dir_path="$current_dir:$dir_path"
> +	initializeSubModule "$1"
> +        cd "$1"
> +	if [ $recurse_verbose -eq 1 ]; then
> +		echo Working in mod $1 @ `pwd` with $2
> +	fi

Always quote variable references unless you mean you want field
splitting.  Even when you know $1 and $2 do not have IFS
characters, to make it easier to readers.

> +        eval "$2"
> +	if [ -f .gitmodules ]; then
> +                for mod_path in `grep "path =" .gitmodules | awk
> '{print $3}'`; do
> +                        traverseModule "$mod_path" "$2"
> +                done
> +        fi
> +	old_dir=$(echo $dir_path | cut -d':' -f1-1)
> +	length_old_dir=`expr "$old_dir" : '.*'`
> +	cd $old_dir
> +	index=$(echo "$length_old_dir+2" | bc)
> +	dir_path=`echo $dir_path $index | awk '{print substr($1, $2)}'`

This dir_path separated with ":" and shuffling the $cwd with
chdir'ing around makes me say "Yuck".  Is it essential that
these operation in the submodule happen in the same process?
IOW, wouldn't it be enough to do something like:


	initialize_submodule "$1"
        (
        	cd "$1"
                if test -n "$recursive_verbose"
                then
                	echo "Working in module $1 with $2"
		fi
                eval "$2"
		if test -f .gitmodules
                then
                	for p in `sed -n -e 's/^path = //p' .gitmodules`
			do
                        	traverse_module "$p" "$2"
			done
		fi
	)

> +}
> +
> +# Propagates or recurses over all the submodules at any
> +# depth with any git command, e.g. git-clone, git-status,
> +# git-commit etc., with the arguments supplied exactly as
> +# it would have been supplied to the command otherwise.
> +# This actually starts the recursive propagation
> +propagate() {
> +	project_home=`pwd`
> +	echo Project Home: $project_home
> +	if [ -d $project_home/.git/ ]; then
> +		git_command=$1
> +		shift
> +		command_arguments=""
> +		for arg in "$@"; do

That 'in "$@"' is distracting.

	for arg
        do
		...

is enough.

> +			if [ `expr index "$arg" ' '` -gt 0 ]; then

Do we ever use `expr index` anywhere else?  I thought we fixed
that non-portability.

> +				arg="\"$arg\""
> +			fi
> +			command_arguments="$command_arguments $arg"
> +		done
> +		if [ $recurse_verbose -eq 1 ]; then
> +			echo GIT Command git-$git_command with arguments\($#\) "$command_arguments"
> +		fi
> +		main_command="git-$git_command $command_arguments"
> +		eval $main_command

This feels like a sloppy quoting, although I haven't looked at
the code very deeply.  Does it work when $arg has funny letters
like backslash, double-quote and or backquote?

> @@ -286,6 +359,17 @@ do
>  	-*)
>  		usage
>  		;;
> +	recurse)
> +		recurse=1
> +		case "$2" in
> +			-v)
> +				recurse_verbose=1
> +				shift
> +				;;
> +		esac
> +		shift
> +		break
> +		;;

I was ahead of myself earlier but I think it makes more sense to
pretend (at the command line syntax level) that --recursive is
an option to other commands.

> @@ -303,17 +387,21 @@ case "$add,$branch" in
>  	;;
>  esac
>
> -case "$add,$init,$update,$status,$cached" in
> -1,,,,)
> +
> +case "$add,$init,$update,$recurse,$status,$cached" in
> +1,,,,,)
>  	module_add "$@"
>  	;;
> -,1,,,)
> +,1,,,,)
>  	modules_init "$@"
>  	;;
> -,,1,,)
> +,,1,,,)
>  	modules_update "$@"
>  	;;
> -,,,*,*)
> +,,,1,,)
> +	propagate "$@"
> +	;;
> +,,,,*,*)
>  	modules_list "$@"
>  	;;
>  *)

I've always hated this part of the script.  How about a bit of
clean-up patch first before adding $recurse or anything else, to
introduce command variable and do:

	case "$command" in
        add)
        	module_add "$@"
                ;;
	init)
        	module_init "$@"
                ;;
                ...
	*)
        	modules_list "$@"
                ;;
	esac

or even just a single:

	"module_$command" "$@"

^ permalink raw reply

* Re: [PATCH] Added initialize and update support for submodule in git clone
From: Junio C Hamano @ 2008-01-08  6:19 UTC (permalink / raw)
  To: Imran M Yousuf; +Cc: git
In-Reply-To: <7bfdc29a0801071922h3656a576wbd87e84bfa663d5a@mail.gmail.com>

"Imran M Yousuf" <imyousuf@gmail.com> writes:

> This patch adds support for initializing and updating submodules when
> a repo is cloned. The advantage it adds is, the user actually does not
> have to know whether it has a module or not and if it does to what
> depth and path. For this I added a option -w or --with-submodule for
> initializing and updating during clone stage.

For everything else, I strongly agree [*1*] that the notion that
all subprojects are populated is a bug.  I am not convinced the
all-or-nothing approach you implemented in "git clone" is useful
outside small toy projects where all of your users are almost
always interested in everything (which inevitably invites a very
valid question: why use submodule at all then?), but in the very
narrow special case of "clone", all-or-nothing is the best you
can do without giving additional hints somewhere in-tree
(perhaps enhanced .gitmodules entries), and it certainly is
better than "you do not have any choice --- you only get the
toplevel".

> Following is the diff with git-clone 1.5.3.7; I also attached the diff
> and modified file in the attachment.

The same comment as diff plus attachment applies to this patch
as the other message.  Also please do not base new development
on 4-digit maintenance releases, which are meant to contain only
bugfixes and no new features.  A patch like this, primarily for
discussion and not for immediate inclusion, is Ok, but it is
better to get into the habit of producing applicable patches
earlier rather than later.

I'll step aside and let others discuss code and design of the
patch.

[Reference]

*1* http://thread.gmane.org/gmane.comp.version-control.git/44106/focus=44308

^ permalink raw reply

* Re: [PATCH] Documentation: config: add 'help.*' and 'instaweb.*' variables.
From: Junio C Hamano @ 2008-01-08  6:27 UTC (permalink / raw)
  To: Christian Couder; +Cc: git
In-Reply-To: <20080108045514.1a506761.chriscool@tuxfamily.org>

Christian Couder <chriscool@tuxfamily.org> writes:

> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>

Thanks.  I already had Dan's s/gitlink/linkgit/ patch in my tree
to work aroudn AscciDoc issues but adjusting the patch was
trivial.

> @@ -843,4 +871,8 @@ receive.denyNonFastForwards::
>  transfer.unpackLimit::
>  	When `fetch.unpackLimit` or `receive.unpackLimit` are
>  	not set, the value of this variable is used instead.
> +
> +web.browser::
> +	Specify a web browser that may be used by some commands.
> +	Currently only gitlink:git-instaweb[1] and gitlink:git-help[1]
> +	may use it.
> -- 
> 1.5.4.rc2.38.gd6da3

Somebody seems to have recounted the patch lines incorrectly
here.  The hunk header should have read "@@ -843,3 +871,8 @@".

^ permalink raw reply

* Re: [PATCH] Added recurse command to git submodule
From: Imran M Yousuf @ 2008-01-08  6:57 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v3at8yiq4.fsf@gitster.siamese.dyndns.org>

Hi Junio,

Thanks for the comments.
FIrstly, yes I did not mean for inclusion right now, but rather for
comment. I am already working with the branched out versions of the
files.
Secondly, I should apologize for messing the patches, as I read the
SubmittingPatches actually after sending out the patches. From next
time, I will try to follow the document strictly.
Sorry for mixing camel case, being a Java developer I always tend to
use them, but will fix them right now :). Will be also changing the
comments. I will also change the for loop to as you suggested.
Thanks a lot for the chdir solution. I actually did not that it could
be done; that saves a lot of effort. Will surely change it
accordingly.
I was actually not planning to introduce git submodule init
--recursive or git submodule update --recursive; but I will also
introduce it. Just wanted to clarify that only git submodule init will
behave as it used to earlier and there is no recursion involved.

>
> > +                             arg="\"$arg\""
> > +                     fi
> > +                     command_arguments="$command_arguments $arg"
> > +             done
> > +             if [ $recurse_verbose -eq 1 ]; then
> > +                     echo GIT Command git-$git_command with arguments\($#\) "$command_arguments"
> > +             fi
> > +             main_command="git-$git_command $command_arguments"
> > +             eval $main_command
>
> This feels like a sloppy quoting, although I haven't looked at
> the code very deeply.  Does it work when $arg has funny letters
> like backslash, double-quote and or backquote?

it does work if $arg has double-quote (commit -m "commit message"), I
will also test with the other 2 characters you mentioned.

I just wanted to confirm that I will submit the patch for commands of
submodule by today. I do agree with having --recursive option with all
the commands, but, IMHO, as it is particularly useful for submodules
only it also makes sense if it is a separate command for submodule.

At first I will make the command change and send the patch today and
then make the other patches and send them over.

Thank you once again for the hints.

Imran

On Jan 8, 2008 11:44 AM, Junio C Hamano <gitster@pobox.com> wrote:
> "Imran M Yousuf" <imyousuf@gmail.com> writes:
>
> > Following is the diff with git-submdoule version 1.5.3.7. I also
> > attached the diff and the modified file in the attachment.
>
> Please do not do this when the submission is for real (I think
> you did not mean this for inclusion but for comment so it is Ok
> this time around), as such a message cannot be processed with
> our automated tools but need to be applied by hand.
>
> Just send a non whitespace-corrupted, plain text patch.  A
> corrupt text patch followed by an attachment is the worst of
> both worlds.
>
> > @@ -251,6 +252,78 @@ modules_list()
> >       done
> >  }
> >
> > +# Simply checks whether the submodule is initialized
> > +# or not. If not initialized it does so.
> > +initializeSubModule() {
> > +     if [ ! -d "$1"/.git ]; then
> > +             if [ $recurse_verbose -eq 1 ]; then
> > +                     echo Initializing and updating "$1"
> > +             fi
> > +             git-submodule init "$1"; git-submodule update "$1"
> > +     fi
> > +}
>
> The comment above sounds quite wrong, isn't it?  It is not just
> "simply check" but actively makes sure it is initialized.
>
> Do we use CamelCase in our shell script?
>
> Making -r to always recurse _fully_ feels quite wrong.  It is
> one thing to allow "git submodule init --recursive" to recurse
> fully and initialize everything, but it is another thing to
> force full instantiation of submodules that the user _chose_ not
> to check out, when the user has checkout of some but not all
> submodules and asks "git submodule update --recursive".
>
> > +# This actually traverses the module; checks
> > +# whether the module is initialized or not.
> > +# if not initialized, then done so and then the
> > +# intended command is evaluated. Then it
> > +# recursively goes into it modules.
> > +traverseModule() {
> > +     current_dir=`pwd`
> > +     dir_path="$current_dir:$dir_path"
> > +     initializeSubModule "$1"
> > +        cd "$1"
> > +     if [ $recurse_verbose -eq 1 ]; then
> > +             echo Working in mod $1 @ `pwd` with $2
> > +     fi
>
> Always quote variable references unless you mean you want field
> splitting.  Even when you know $1 and $2 do not have IFS
> characters, to make it easier to readers.
>
> > +        eval "$2"
> > +     if [ -f .gitmodules ]; then
> > +                for mod_path in `grep "path =" .gitmodules | awk
> > '{print $3}'`; do
> > +                        traverseModule "$mod_path" "$2"
> > +                done
> > +        fi
> > +     old_dir=$(echo $dir_path | cut -d':' -f1-1)
> > +     length_old_dir=`expr "$old_dir" : '.*'`
> > +     cd $old_dir
> > +     index=$(echo "$length_old_dir+2" | bc)
> > +     dir_path=`echo $dir_path $index | awk '{print substr($1, $2)}'`
>
> This dir_path separated with ":" and shuffling the $cwd with
> chdir'ing around makes me say "Yuck".  Is it essential that
> these operation in the submodule happen in the same process?
> IOW, wouldn't it be enough to do something like:
>
>
>         initialize_submodule "$1"
>         (
>                 cd "$1"
>                 if test -n "$recursive_verbose"
>                 then
>                         echo "Working in module $1 with $2"
>                 fi
>                 eval "$2"
>                 if test -f .gitmodules
>                 then
>                         for p in `sed -n -e 's/^path = //p' .gitmodules`
>                         do
>                                 traverse_module "$p" "$2"
>                         done
>                 fi
>         )
>
> > +}
> > +
> > +# Propagates or recurses over all the submodules at any
> > +# depth with any git command, e.g. git-clone, git-status,
> > +# git-commit etc., with the arguments supplied exactly as
> > +# it would have been supplied to the command otherwise.
> > +# This actually starts the recursive propagation
> > +propagate() {
> > +     project_home=`pwd`
> > +     echo Project Home: $project_home
> > +     if [ -d $project_home/.git/ ]; then
> > +             git_command=$1
> > +             shift
> > +             command_arguments=""
> > +             for arg in "$@"; do
>
> That 'in "$@"' is distracting.
>
>         for arg
>         do
>                 ...
>
> is enough.
>
> > +                     if [ `expr index "$arg" ' '` -gt 0 ]; then
>
> Do we ever use `expr index` anywhere else?  I thought we fixed
> that non-portability.
>
> > +                             arg="\"$arg\""
> > +                     fi
> > +                     command_arguments="$command_arguments $arg"
> > +             done
> > +             if [ $recurse_verbose -eq 1 ]; then
> > +                     echo GIT Command git-$git_command with arguments\($#\) "$command_arguments"
> > +             fi
> > +             main_command="git-$git_command $command_arguments"
> > +             eval $main_command
>
> This feels like a sloppy quoting, although I haven't looked at
> the code very deeply.  Does it work when $arg has funny letters
> like backslash, double-quote and or backquote?
>
> > @@ -286,6 +359,17 @@ do
> >       -*)
> >               usage
> >               ;;
> > +     recurse)
> > +             recurse=1
> > +             case "$2" in
> > +                     -v)
> > +                             recurse_verbose=1
> > +                             shift
> > +                             ;;
> > +             esac
> > +             shift
> > +             break
> > +             ;;
>
> I was ahead of myself earlier but I think it makes more sense to
> pretend (at the command line syntax level) that --recursive is
> an option to other commands.
>
> > @@ -303,17 +387,21 @@ case "$add,$branch" in
> >       ;;
> >  esac
> >
> > -case "$add,$init,$update,$status,$cached" in
> > -1,,,,)
> > +
> > +case "$add,$init,$update,$recurse,$status,$cached" in
> > +1,,,,,)
> >       module_add "$@"
> >       ;;
> > -,1,,,)
> > +,1,,,,)
> >       modules_init "$@"
> >       ;;
> > -,,1,,)
> > +,,1,,,)
> >       modules_update "$@"
> >       ;;
> > -,,,*,*)
> > +,,,1,,)
> > +     propagate "$@"
> > +     ;;
> > +,,,,*,*)
> >       modules_list "$@"
> >       ;;
> >  *)
>
> I've always hated this part of the script.  How about a bit of
> clean-up patch first before adding $recurse or anything else, to
> introduce command variable and do:
>
>         case "$command" in
>         add)
>                 module_add "$@"
>                 ;;
>         init)
>                 module_init "$@"
>                 ;;
>                 ...
>         *)
>                 modules_list "$@"
>                 ;;
>         esac
>
> or even just a single:
>
>         "module_$command" "$@"
>
>
>



-- 
Imran M Yousuf

^ permalink raw reply

* Re: how to use git merge -s subtree?
From: Junio C Hamano @ 2008-01-08  6:57 UTC (permalink / raw)
  To: Sean; +Cc: David Soria Parra, git
In-Reply-To: <BAYC1-PASMTP152065390CFAF8C09F0B60AE480@CEZ.ICE>

Sean <seanlkml@sympatico.ca> writes:

> In the case of the "--follow" option though, the user might be forgiven
> for thinking in terms of files rather than paths.  Even the git-log
> documentation says for "--follow", "Continue listing the history of a
> file beyond renames".   Which at least implies that Git knows about
> file history, rather than just paths.

But you know git does not know nor care about "file" history.

And the thing is, I just tried this:

  $ git log --follow --pretty=short --stat gitk-git/gitk | head -n 20
  commit 62ba5143ec2ab9d4083669b1b1679355e7639cd5
  Author: Junio C Hamano <gitster@pobox.com>

      Move gitk to its own subdirectory

   gitk => gitk-git/gitk |    0 
   1 files changed, 0 insertions(+), 0 deletions(-)

  commit 7388bcbc5431552718dde5c3259d861d2fa75a12
  Author: Paul Mackerras <paulus@samba.org>

      gitk: Use the UI font for the diff/old version/new version radio buttons

   gitk |    6 +++---
   1 files changed, 3 insertions(+), 3 deletions(-)

  commit cca5d946d692fde7ea5408a694cb4b1c97a5a838
  Author: Paul Mackerras <paulus@samba.org>

      gitk: Simplify the code for finding commits

So there is something else going on, if David actually tried to
follow "B/foo" that was subtree-merged from a parent that had it
at toplevel "foo" and "log --follow" did not work for him.

Two things that come to mind offhand are that (1) --follow looks
for a path that has similar contents elsewhere only when the
path it is following in the child disappears in the parent.  So
if you start from B/foo that was subtree-merged (i.e. the other
parent has foo at the top) into a parent that already had B/foo,
it will not follow the other parent that does not have B/foo;
(2) I do not know if the original example by David tried to use
"-n $count" offhand, but it seems that currently --follow does
not play well with -n (try the above gitk-git/gitk without
piping the result into "head -n 20" but instead by limiting with
"git log -3 --follow ..."); if that is the case that definitely
is a bug.

^ permalink raw reply

* Re: CRLF problems with Git on Win32
From: Steffen Prohaska @ 2008-01-08  7:02 UTC (permalink / raw)
  To: Junio C Hamano, Linus Torvalds
  Cc: Johannes Schindelin, Robin Rosenberg, Jeff King, Peter Karlsson,
	Git Mailing List, msysGit
In-Reply-To: <7vzlvhxpda.fsf-jO8aZxhGsIagbBziECNbOZn29agUkmeCHZ5vskTnxNA@public.gmane.org>



On Jan 7, 2008, at 11:06 PM, Junio C Hamano wrote:

> Steffen Prohaska <prohaska-wjoc1KHpMeg@public.gmane.org> writes:
>
>> I believe the main question is which type of projects we would like
>> to support by our default.  For real cross-platform projects that  
>> will
>> be checked out on Windows and Unix we should choose
>> "core.autocrlf true" as our default.  But if our default are native
>> Windows projects that will never be checked out on Unix, then we
>> should not set core.autocrlf by default.
>
> If the primary target is native Windows projects that wants CRLF
> in the work tree, you could still set core.autocrlf.  Your
> checkouts will be with CRLF.  And someday perhaps somebody may
> offer porting that to UNIX and his checkout will be without CR.
>
> So wouldn't the categorization be more like this?
>
>  - "real cross-platform" would want core.autocrlf = true;
>
>  - "native Windows" can work either way;

But core.autocrlf  = true has a slight danger of data corruption.
AFAIK, git's binary detection checks the first "few" bytes (with
few = 8000).  This may be sufficient in most case, but I already
met a file that was wrongly classified.  (A File format that
starts with a large ASCII header and has chunks of binary data
attached later.)


>  - "originated from UNIX" would be helped with core.autocrlf = true;

I'd say "could be helped".  For the msysgit development, for
example, we do _not_ want to have core.autocrlf = true but
prefer to preserve the Unix line ending even when working on
Windows.  We have only few Windows-specific files that are
committed with CRLF.  We _know_ the problem and we explicitly
handle it.


I believe, best would be if a line ending policy could be
configured for a project.  Then, the decision could be made once
for the project and should be enforced on all clones.  But
currently git has no concept for this.

A sound policy for "real cross-platform" is that CRLF must never
enter the repository unless git detects a file as binary, or a
file is explicitly listed in .gitattributes.  It doesn't really
matter if Windows users check out files with CRLF or LF.  It only
matters that they'll never commit a file with CRLF.  Note, the
same is true for Unix users.  People could send code by email or
copy source files from Windows to Unix machines.  Then, CRLF
would enter the repo on Unix.  So the least that should be set
for this type of projects on any OS is core.autocrlf = input.
On Windows, core.autocrlf = true is probably more natural.

I like Linus' idea of "warn" or Gregory's "fail".

Would "warn/fail" be the default on Unix, too?  Then Unix users
would also be forced to make an explicit choice.  Maybe some day
they want to check out their project on Windows and they should
be prepared now.  For typical files, the warning (or error) would
never trigger.  But maybe one day they copy a file from a Windows
machine and forget to run dos2unix.  In this case, git would warn
them unless they set "core.autocrlf = false".

I'm asking the last question because every Unix developer should
think about the option, too.  Neither Unix or Windows are causing
the problem alone.  It's the combination in a cross-platform
project.  Git could ensure that any repository is in principal
prepared for cross-platform, unless explicitly told not to do so.

So, would you, as Linux developers, like to have (or accept)
"warn/fail" as your default?

This would make things easy for the msysgit project:  No Windows
specific configuration; just official git.

	Steffen

^ permalink raw reply

* Re: [PATCH] Documentation: config: add 'help.*' and 'instaweb.*' variables.
From: Christian Couder @ 2008-01-08  7:43 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vmyrgx26h.fsf@gitster.siamese.dyndns.org>

Le mardi 8 janvier 2008, Junio C Hamano a écrit :
> Christian Couder <chriscool@tuxfamily.org> writes:
> > +web.browser::
> > +	Specify a web browser that may be used by some commands.
> > +	Currently only gitlink:git-instaweb[1] and gitlink:git-help[1]
> > +	may use it.
> > --
> > 1.5.4.rc2.38.gd6da3
>
> Somebody seems to have recounted the patch lines incorrectly
> here.  The hunk header should have read "@@ -843,3 +871,8 @@".

Yeah, sorry about that. I added "gitlink:" before "git-help[1]" and 
moved "may use" to the next line before "it" just before sending the patch.
This probably made xemacs recount badly.

By the way I had no comment on my RFC/Patch to run the test scripts under 
valgrind. Maybe it's useless because it doesn't find any bug right now.

Thanks,
Christian.

^ permalink raw reply

* Re: [PATCH] Documentation: config: add 'help.*' and 'instaweb.*' variables.
From: Junio C Hamano @ 2008-01-08  7:40 UTC (permalink / raw)
  To: Christian Couder; +Cc: git
In-Reply-To: <200801080843.35693.chriscool@tuxfamily.org>

Christian Couder <chriscool@tuxfamily.org> writes:

> By the way I had no comment on my RFC/Patch to run the test scripts under 
> valgrind. Maybe it's useless because it doesn't find any bug right now.

I found it interesting myself.  I did not know how well it fits
into the rest of the testing infrastructure, though.  Perhaps
you would want to reopen the issue after 1.5.4?

^ permalink raw reply

* git-diff across branches?
From: Gonzalo Garramuño @ 2008-01-08  8:44 UTC (permalink / raw)
  To: git


I was wondering if there was a way to make a git-diff across (local) 
branches.

Something like:

$ git-diff --branch test1 HEAD --branch test2 HEAD  file.cpp
(would show a diff for file.cpp between test1 HEAD and test2 HEAD)



-- 
Gonzalo Garramuño
ggarra@advancedsl.com.ar

AMD4400 - ASUS48N-E
GeForce7300GT
Xubuntu Gutsy

^ permalink raw reply

* [ANNOUNCE] GIT 1.5.3.8
From: Junio C Hamano @ 2008-01-08  8:54 UTC (permalink / raw)
  To: git; +Cc: linux-kernel

The latest maintenance release GIT 1.5.3.8 is available at the
usual places:

  http://www.kernel.org/pub/software/scm/git/

  git-1.5.3.8.tar.{gz,bz2}			(tarball)
  git-htmldocs-1.5.3.8.tar.{gz,bz2}		(preformatted docs)
  git-manpages-1.5.3.8.tar.{gz,bz2}		(preformatted docs)
  RPMS/$arch/git-*-1.5.3.8-1.$arch.rpm	(RPM)

Hopefully this will be the last maintenance of 1.5.3 series, as
we are nearing -rc3 on the 1.5.4 front.

----------------------------------------------------------------

Changes since v1.5.3.7 are as follows:

David Symonds (1):
      Change from using email.com to example.com as example
      domain, as per RFC 2606.

Eric Wong (2):
      git-svn: support for funky branch and project names over HTTP(S)
      git-svn: clarify the "Ignoring error from SVN" piece

Jeff King (3):
      t9600: test cvsimport from CVS working tree
      clone: correctly report http_fetch errors
      git-send-email: avoid duplicate message-ids

Jim Meyering (1):
      config.c:store_write_pair(): don't read the byte before a
      malloc'd buffer.

Junio C Hamano (3):
      git grep shows the same hit repeatedly for unmerged paths
      git-am -i: report rewritten title
      GIT 1.5.3.8

Nguyễn Thái Ngọc Duy (3):
      Add missing inside_work_tree setting in setup_git_directory_gently
      Do check_repository_format() early
      Do check_repository_format() early (re-fix)

^ permalink raw reply

* Re: CRLF problems with Git on Win32
From: Marius Storm-Olsen @ 2008-01-08  8:55 UTC (permalink / raw)
  To: torvalds-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b
  Cc: Junio C Hamano, Steffen Prohaska, Johannes Schindelin,
	Robin Rosenberg, Jeff King, Peter Karlsson, Git Mailing List,
	msysgit-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <alpine.LFD.1.00.0801071457040.3148-5CScLwifNT1QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org>


Linus Torvalds said the following on 07.01.2008 23:58:
> 
> 
> On Mon, 7 Jan 2008, Junio C Hamano wrote:
>> So wouldn't the categorization be more like this?
> 
> Well, one thng we could do is to add a new concept, namely
> 
> 	core.autocrlf = warn
> 
> and make *that* the default.
> 
> It would do the check, but not actually convert anything, just warn about 
> it.
> 
> Then, it's up to the user to set it explicitly to "true" or "false", 
> unless they just like seeing that warning a million times ;)
> 
> That might be acceptable to most people.

I actually would want the default to be
     core.autocrlf = windows

Meaning, it would be true on Windows platforms, and warn on all 
others. That way it would work as expected in 90% of the time, namely 
that files are added to the repo with unix line endings. We could then 
add the following warning when you try to add a CRLF file on 
non-Windows platforms:

   * CRLF line endings detected for text files: <foo>, <bar>, <baz>
   Consider adding the following to a .gitattributes file to
   maintain the CRLF line endings on all platforms:
     <foo> = -crlf
     <bar> = -crlf
     <baz> = -crlf

Maybe then can we lure non-Windows users to add these required 
.gitattributes files for files that need to be CRLF on all platforms; 
instead of shoving the whole burden of maintaining a proper 
cross-platform repo onto the Windows users alone.

/me braces for the "it's your fault for working on Windows in the 
first place!" flood ;-)

Of course, setting the core.autocrlf = true|false should not show the 
warning, for users who don't care about repo portability to Windows 
anyways.

--
.marius

^ permalink raw reply

* Re: git-diff across branches?
From: Jeff King @ 2008-01-08  8:57 UTC (permalink / raw)
  To: Gonzalo Garramuño; +Cc: git
In-Reply-To: <478337DE.7@advancedsl.com.ar>

On Tue, Jan 08, 2008 at 05:44:14AM -0300, Gonzalo Garramuño wrote:

> I was wondering if there was a way to make a git-diff across (local)  
> branches.
>
> Something like:
>
> $ git-diff --branch test1 HEAD --branch test2 HEAD  file.cpp
> (would show a diff for file.cpp between test1 HEAD and test2 HEAD)

I think you are mistaken about how HEAD works; it is a pointer to a
particular branch. So there is no "HEAD" for test1; there is simply
test1, and from time to time your repository's HEAD points to test1.

However, that makes things easier. You can simply do this:

  git-diff test1 test2 file.cpp

Unless you mean that you have two separate repositories, test1 and
test2. In which case each _does_ have its own HEAD, and you will have to
fetch from one repo into the other to get your answer:

  # go into one of the repos
  cd test1
  # fetch the 'master' ref from the other repo and store it in this repo
  # using the name 'test2'
  git fetch ../test2 master:test2
  # now we can diff between them
  git diff HEAD test2 file.cpp

-Peff

^ permalink raw reply

* A note from the maintainer
From: Junio C Hamano @ 2008-01-08  8:57 UTC (permalink / raw)
  To: git

Now a new maitenance release is out and we are reasonably in a
good shape to expect smooth progress toward the next feature
release, it's a good time to welcome new people to the list.
This message talks about how git.git is managed, and how you can
work with it.

* IRC and Mailing list

Many active members of development community hang around on #git
IRC channel on Freenode.  Its log is available at:

        http://colabti.de/irclogger/irclogger_log/git

The development however is primarily done on this mailing list
you are reading right now.  If you have patches, please send
them to the list, following Documentation/SubmittingPatches.

I usually try to read all patches posted to the list, and follow
almost all the discussions on the list, unless the topic is about an
obscure corner that I do not personally use.  But I am obviously not
perfect.  If you sent a patch that you did not hear from anybody for
three days, that is a very good indication that it was dropped on the
floor --- please do not hesitate to remind me.

The list archive is available at a few public sites as well:

        http://news.gmane.org/gmane.comp.version-control.git/
        http://marc.theaimsgroup.com/?l=git
        http://www.spinics.net/lists/git/

and some people seem to prefer to read it over NNTP:

        nntp://news.gmane.org/gmane.comp.version-control.git

When you point at a message in a mailing list archive, using
gmane is often the easiest to follow by readers, like this:

        http://thread.gmane.org/gmane.comp.version-control.git/27/focus=217

as it also allows people who subscribe to the mailing list as
gmane newsgroup to "jump to" the article.

* Repositories, branches and documentation.

My public git.git repository is at:

        git://git.kernel.org/pub/scm/git/git.git/

Immediately after I publish to the primary repository at kernel.org, I
also push into an alternate here:

        git://repo.or.cz/alt-git.git/

Impatient people might have better luck with the latter one.

Their gitweb interfaces are found at:

        http://git.kernel.org/?p=git/git.git
        http://repo.or.cz/w/alt-git.git

There are three branches in git.git repository that are not
about the source tree of git: "todo", "html" and "man".  The
first one was meant to contain TODO list for me, but I am not
good at maintaining such a list so it is not as often updated as
it could/should be.  It also contains some helper scripts I use
to maintain git.

The "html" and "man" are autogenerated documentation from the
tip of the "master" branch; the tip of "html" is extracted to be
visible at kernel.org at:

        http://www.kernel.org/pub/software/scm/git/docs/

The above URL is the top-level documentation page, and it has
links to documentation of older releases.

The script to maintain these two documentation branches are
found in "todo" branch as dodoc.sh, if you are interested.  It
is a good demonstration of how to use an update hook to automate
a task.

There are four branches in git.git repository that track the
source tree of git: "master", "maint", "next", and "pu".  I may
add more maintenance branches (e.g. "maint-1.5.3") if we have
hugely backward incompatible feature updates in the future to keep
an older release alive; I may not, but the distributed nature of
git means any volunteer can run a stable-tree like that himself.

The "master" branch is meant to contain what are very well
tested and ready to be used in a production setting.  There
could occasionally be minor breakages or brown paper bag bugs
but they are not expected to be anything major, and more
importantly quickly and trivially fixable.  Every now and
then, a "feature release" is cut from the tip of this branch and
they typically are named with three dotted decimal digits.  The
last such release was v1.5.3 done on Sep 2nd last year.  You
can expect that the tip of the "master" branch is always more
stable than any of the released versions.

Whenever a feature release is made, "maint" branch is forked off
from "master" at that point.  Obvious, safe and urgent fixes
after a feature release are applied to this branch and
maintenance releases are cut from it.  The maintenance releases
are named with four dotted decimal, named after the feature
release they are updates to; the last such release was v1.5.3.8,
made tonight.  New features never go to this branch.  This
branch is also merged into "master" to propagate the fixes forward.

A trivial and safe enhancement goes directly on top of "master".
A new development, either initiated by myself or more often by
somebody who found his or her own itch to scratch, does not
usually happen on "master", however.  Instead, a separate topic
branch is forked from the tip of "master", and it first is
tested in isolation; I may make minimum fixups at this point.
Usually there are a handful such topic branches that are running
ahead of "master" in git.git repository.  I do not publish the
tip of these branches in my public repository, however, partly
to keep the number of branches that downstream developers need
to worry about low, and primarily because I am lazy.

I judge the quality of topic branches, taking advices from the
mailing list discussions.  Some of them start out as "good idea
but obviously is broken in some areas (e.g. breaks the existing
testsuite)" and then with some more work (either by the original
contributor or help from other people on the list) becomes "more
or less done and can now be tested by wider audience".  Luckily,
most of them start out in the latter, better shape.

The "next" branch is to merge and test topic branches in the
latter category.  In general, the branch always contains the tip
of "master".  It might not be quite rock-solid production ready,
but is expected to work more or less without major breakage.  I
usually use "next" version of git for my own work, so it cannot
be _that_ broken to prevent me from pushing the changes out.
The "next" branch is where new and exciting things take place.

The above three branches, "master", "maint" and "next" are never
rewound, so you should be able to safely track them (this
automatically means the topics that have been merged into "next"
are never rebased, and you can find the tip of topic branches you
are interested in from the output of "git log next").

The "pu" (proposed updates) branch bundles all the remainder of
topic branches.  The "pu" branch, and topic branches that are
only in "pu", are subject to rebasing in general.  By the above
definition of how "next" works, you can tell that this branch
will contain quite experimental and obviously broken stuff.

When a topic that was in "pu" proves to be in testable shape, it
graduates to "next".  I do this with:

        git checkout next
        git merge that-topic-branch

Sometimes, an idea that looked promising turns out to be not so
good and the topic can be dropped from "pu" in such a case.

A topic that is in "next" is expected to be tweaked and fixed to
perfection before it is merged to "master" (that's why "master"
can be expected to stay very stable).  Similarly to the above, I
do it with this:

        git checkout master
        git merge that-topic-branch
        git branch -d that-topic-branch

Note that being in "next" is not a guarantee to appear in the
next release (being in "master" is such a guarantee, unless it
is later found seriously broken and reverted), or even in any
future release.  There even were cases that topics needed
reverting a few commits in them before graduating to "master",
or a topic that already was in "next" were entirely reverted
from "next" because fatal flaws were found in them later.

Starting from v1.5.0, "master" and "maint" have release notes
for the next release in Documentation/RelNotes-* files, so that
I do not have to run around summarizing what happened just
before the release.


* Other people's trees, trusted lieutenants and credits.

Documentation/SubmittingPatches outlines who your changes should
be sent to.  As described in contrib/README, I would delegate
fixes and enhancements in contrib/ area to primary contributors
of them.

Although the following are included in git.git repository, they
have their own authoritative repository and maintainers:

 git-gui/ -- this subdirectory comes from Shawn Pearce's git-gui
             project, which is found at:

             git://repo.or.cz/git-gui.git

 gitk     -- this file is maintained by Paul Mackerras, at:

             git://git.kernel.org/pub/scm/gitk/gitk.git

I would like to thank everybody who helped to raise git into the
current shape.  Especially I would like to thank the git list
regulars whose help I have relied on and expect to continue
relying on heavily:

 - Linus on general design issues.

 - Linus, Shawn Pearce, Johannes Schindelin, Nicolas Pitre,
   Réne Scharfe and Jeff King on general implementation issues.

 - Shawn and Nicolas Pitre on pack issues.

 - Martin Langhoff and Frank Lichtenheld on cvsserver and cvsimport.

 - Paul Mackerras on gitk.

 - Eric Wong on git-svn.

 - Jakub Narebski, Petr Baudis, and Luben Tuikov on gitweb.

 - J. Bruce Fields on documentaton issues.

 - Johannes Schindelin and Johannes Sixt for their effort to
   move things forward on the Windows front.  Although my
   repository does not have much from the effort of MinGW team,
   I expect a merge into mainline will happen so that everybody
   can work from the same codebase.

 - People on non-Linux platforms for keeping their eyes on
   portability; especially, Randal Schwartz, Theodore Ts'o,
   Jason Riedy, Thomas Glanzmann, but countless others as well.

* This document

The latest copy of this document is found in git.git repository,
on 'todo' branch, as MaintNotes.

^ permalink raw reply

* Re: CRLF problems with Git on Win32
From: Junio C Hamano @ 2008-01-08  7:29 UTC (permalink / raw)
  To: public-prohaska-wjoc1KHpMeg
  Cc: Linus Torvalds, Johannes Schindelin, Robin Rosenberg, Jeff King,
	Peter Karlsson, Git Mailing List, msysGit
In-Reply-To: <5310CD2F-C3B4-404A-9C2E-1D3084B5CC96@zib.de>




Steffen Prohaska <prohaska-wjoc1KHpMeg@public.gmane.org> writes:

> But core.autocrlf  = true has a slight danger of data corruption.
> AFAIK, git's binary detection checks the first "few" bytes (with
> few = 8000).  This may be sufficient in most case, but I already
> met a file that was wrongly classified.  (A File format that
> starts with a large ASCII header and has chunks of binary data
> attached later.)

I presume that's where .gitattributes kicks in.

> I like Linus' idea of "warn" or Gregory's "fail".

Yeah, that feels like a sensible thing to do.

> I'm asking the last question because every Unix developer should
> think about the option, too.  Neither Unix or Windows are causing
> the problem alone.

That's the logical conclusion.

If you are introducing crlf = warn, that means you are declaring
that CRLF should be treated as a disease, and that should apply
everywhere, not just on Windows (which some people may consider
a disease itself, but that is a separate topic).

^ permalink raw reply

* Re: A note from the maintainer
From: Jakub Narebski @ 2008-01-08  9:57 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vir24vgmy.fsf@gitster.siamese.dyndns.org>

Junio C Hamano <gitster@pobox.com> writes:

> * IRC and Mailing list
 
> When you point at a message in a mailing list archive, using
> gmane is often the easiest to follow by readers, like this:
> 
>         http://thread.gmane.org/gmane.comp.version-control.git/27/focus=217
> 
> as it also allows people who subscribe to the mailing list as
> gmane newsgroup to "jump to" the article.

Isn't it better to give Message-ID (perhaps with addition to
some archive URLs)? This way one can search his/her own mail
archive; also (I think) all git mail archives support finding
article with given Message-ID (e.g. http://mid.gmane.org/<msg-id>
for GMane).
 
> * Repositories, branches and documentation.

> There are four branches in git.git repository that track the
> source tree of git: "master", "maint", "next", and "pu".  I may
> add more maintenance branches (e.g. "maint-1.5.3") if we have
> hugely backward incompatible feature updates in the future to keep
> an older release alive; I may not, but the distributed nature of
> git means any volunteer can run a stable-tree like that himself.

What about "offcuts" branch?

-- 
Jakub Narebski
Poland
ShadeHawk on #git

^ permalink raw reply

* Re: git-diff across branches?
From: Jakub Narebski @ 2008-01-08 10:01 UTC (permalink / raw)
  To: Jeff King; +Cc: Gonzalo Garramuño, git
In-Reply-To: <20080108085705.GA4222@sigill.intra.peff.net>

Jeff King <peff@peff.net> writes:

> On Tue, Jan 08, 2008 at 05:44:14AM -0300, Gonzalo Garramuño wrote:
> 
> > I was wondering if there was a way to make a git-diff across (local)  
> > branches.
> >
> > Something like:
> >
> > $ git-diff --branch test1 HEAD --branch test2 HEAD  file.cpp
> > (would show a diff for file.cpp between test1 HEAD and test2 HEAD)
> 
> I think you are mistaken about how HEAD works; it is a pointer to a
> particular branch. So there is no "HEAD" for test1; there is simply
> test1, and from time to time your repository's HEAD points to test1.
> 
> However, that makes things easier. You can simply do this:
> 
>   git-diff test1 test2 file.cpp

Canonically it is

  # git diff test1 test2 -- file.cpp

but you can also use (for example if file was renamed)

  # git diff test1:file.cpp test2:file.cpp
 
> Unless you mean that you have two separate repositories, test1 and
> test2. In which case each _does_ have its own HEAD, and you will have to
> fetch from one repo into the other to get your answer:
[cut]

Not necessary. If those two repositories are on the same local
filesystem, you can use trick from GitTips:

  http://git.or.cz/gitwiki/GitTips#head-9f79516c05f0c1b51945b848adb3dd1c5a2bf016

  (assuming we are in test1, and ../test2 is relative path to test2)
  # GIT_ALTERNATE_OBJECT_DIRECTORIES=../test2/.git/objects git diff-tree \
     $(GIT_DIR=../test2/.git git rev-parse --verify HEAD) HEAD

-- 
Jakub Narebski
Poland
ShadeHawk on #git

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox