* [PATCH 6/6] Documentation: tweak How Merge Works
From: Jonathan Nieder @ 2010-01-11 8:43 UTC (permalink / raw)
To: git; +Cc: Thomas Rast, Petr Baudis, Junio C Hamano
In-Reply-To: <20100111082123.GA23742@progeny.tock>
Change heading to TRUE MERGE. The whole manual page is about how
merges work.
Start to explain what it means to merge two commits into a single
tree.
Do not assume the commits named on the 'git merge' command line
come from another repository. For simplicity, still assume they
are branch heads for now, though.
Do not give start any list items with `code`; a toolchain bug
makes the resulting nroff look wrong.
Recommend reset --merged for safely cancelling a failed merge.
Cc: Petr Baudis <pasky@suse.cz>
Cc: Junio C Hamano <gitster@pobox.com>
Cc: Thomas Rast <trast@student.ethz.ch>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Documentation/git-merge.txt | 56 +++++++++++++++++++-----------------------
1 files changed, 25 insertions(+), 31 deletions(-)
diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt
index ec9c6d3..7ae0f65 100644
--- a/Documentation/git-merge.txt
+++ b/Documentation/git-merge.txt
@@ -96,62 +96,56 @@ merge commit.
This behavior can be suppressed with the `--no-ff` option.
-include::merge-strategies.txt[]
-
-
-If you tried a merge which resulted in complex conflicts and
-want to start over, you can recover with 'git-reset'.
-
-HOW MERGE WORKS
----------------
-
-A merge is always between the current `HEAD` and one or more
-commits (usually, branch head or tag).
+TRUE MERGE
+----------
Except in a fast-forward merge (see above), the branches to be
merged must be tied together by a merge commit that has both of them
as its parents.
The rest of this section describes this "True merge" case.
-The chosen merge strategy merges the two commits into a single
-new source tree.
When things merge cleanly, this is what happens:
-1. The results are updated both in the index file and in your
- working tree;
-2. Index file is written out as a tree;
+1. A version reconciling the changes from all branches to be
+ merged is written to the index file and your working tree;
+2. The index file is written out as a tree;
3. The tree gets committed; and
4. The `HEAD` pointer gets advanced.
Because of 2., we require that the original state of the index
file matches exactly the current `HEAD` commit; otherwise we
-will write out your local changes already registered in your
+would write out your local changes already registered in your
index file along with the merge result, which is not good.
Because 1. involves only those paths differing between your
-branch and the remote branch you are pulling from during the
-merge (which is typically a fraction of the whole tree), you can
-have local modifications in your working tree as long as they do
-not overlap with what the merge updates.
-
-When there are conflicts, the following happens:
+branch and the other branches (which is typically a fraction of
+the whole tree), you can have local modifications in your
+working tree as long as they do not overlap with what the merge
+updates.
-1. `HEAD` stays the same.
+When it is not obvious how to reconcile the changes, the following
+happens:
-2. Cleanly merged paths are updated both in the index file and
+1. The `HEAD` pointer stays the same.
+2. The `MERGE_HEAD` ref is set to point to the other branch head.
+3. Paths that merged cleanly are updated both in the index file and
in your working tree.
-
-3. For conflicting paths, the index file records up to three
+4. For conflicting paths, the index file records up to three
versions; stage1 stores the version from the common ancestor,
- stage2 from `HEAD`, and stage3 from the remote branch (you
+ stage2 from `HEAD`, and stage3 from `MERGE_HEAD` (you
can inspect the stages with `git ls-files -u`). The working
tree files contain the result of the "merge" program; i.e. 3-way
- merge results with familiar conflict markers `<<< === >>>`.
-
-4. No other changes are done. In particular, the local
+ merge results with familiar conflict markers `<<<` `===` `>>>`.
+5. No other changes are done. In particular, the local
modifications you had before you started merge will stay the
same and the index entries for them stay as they were,
i.e. matching `HEAD`.
+If you tried a merge which resulted in complex conflicts and
+want to start over, you can recover with `git reset --merged`.
+
+include::merge-strategies.txt[]
+
+
HOW CONFLICTS ARE PRESENTED
---------------------------
--
1.6.6
^ permalink raw reply related
* [PATCH 5/6] Documentation: merge: add a section about fast-forward
From: Jonathan Nieder @ 2010-01-11 8:39 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Thomas Rast, Petr Baudis
In-Reply-To: <20100111082123.GA23742@progeny.tock>
Novices sometimes find the behavior of 'git merge' in the
fast-forward case surprising. Add a section to the manual to
describe it more thoroughly.
Cc: Petr Baudis <pasky@suse.cz>,
Cc: Junio C Hamano <gitster@pobox.com>
Cc: Thomas Rast <trast@student.ethz.ch>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Documentation/git-merge.txt | 31 ++++++++++++++++++-------------
1 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt
index 8950aa4..ec9c6d3 100644
--- a/Documentation/git-merge.txt
+++ b/Documentation/git-merge.txt
@@ -82,6 +82,20 @@ the same state that would result from the merge anyway.)
If all named commits are already ancestors of `HEAD`, 'git merge'
will exit early with the message "Already up-to-date."
+FAST-FORWARD MERGE
+------------------
+
+Often the current branch head is an ancestor of the named commit.
+This is the most common case especially when invoked from 'git
+pull': you are tracking an upstream repository, you have committed
+no local changes, and now you want to update to a newer upstream
+revision. In this case, a new commit is not needed to store the
+combined history; instead, the `HEAD` (along with the index) is
+updated to point at the named commit, without creating an extra
+merge commit.
+
+This behavior can be suppressed with the `--no-ff` option.
+
include::merge-strategies.txt[]
@@ -94,19 +108,10 @@ HOW MERGE WORKS
A merge is always between the current `HEAD` and one or more
commits (usually, branch head or tag).
-Two kinds of merge can happen:
-
-* `HEAD` is already contained in the merged commit. This is the
- most common case especially when invoked from 'git pull':
- you are tracking an upstream repository, have committed no local
- changes and now you want to update to a newer upstream revision.
- Your `HEAD` (and the index) is updated to point at the merged
- commit, without creating an extra merge commit. This is
- called "Fast-forward".
-
-* Both the merged commit and `HEAD` are independent and must be
- tied together by a merge commit that has both of them as its parents.
- The rest of this section describes this "True merge" case.
+Except in a fast-forward merge (see above), the branches to be
+merged must be tied together by a merge commit that has both of them
+as its parents.
+The rest of this section describes this "True merge" case.
The chosen merge strategy merges the two commits into a single
new source tree.
--
1.6.6
^ permalink raw reply related
* [PATCH 4/6] Documentation: emphasize when git merge terminates early
From: Jonathan Nieder @ 2010-01-11 8:37 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Thomas Rast, Petr Baudis, git
In-Reply-To: <20100111082123.GA23742@progeny.tock>
A merge-based operation in git can fail in two ways:
- One that stops before touching anything (either your index was
dirty and nothing happened, or your index was clean but you
had local modifications in your work tree).
- Another that goes ahead and results in conflicts.
The 'git merge' manual explains half of the first case as follows:
| A merge is always between the current `HEAD` and one or more
| commits (usually, branch head or tag), and the index file must
| match the tree of `HEAD` commit (i.e. the contents of the last commit)
| when it starts out.
The placement of this sentence makes it easy to skip over, and
its formulation is perhaps too formal to be memorable.
So give this point its own section and expand upon it. Most of
the added text is taken from <http://gitster.livejournal.com/25801.html>.
Cc: Petr Baudis <pasky@suse.cz>,
Cc: Junio C Hamano <gitster@pobox.com>
Cc: Thomas Rast <trast@student.ethz.ch>
Not-signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
This is not signed off because most of the text is from Junio’s
blog. I hope that is okay.
Documentation/git-merge.txt | 34 ++++++++++++++++++++++++----------
1 files changed, 24 insertions(+), 10 deletions(-)
diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt
index e29bb97..8950aa4 100644
--- a/Documentation/git-merge.txt
+++ b/Documentation/git-merge.txt
@@ -60,6 +60,28 @@ include::merge-options.txt[]
least one <remote>. Specifying more than one <remote>
obviously means you are trying an Octopus.
+PRE-MERGE CHECKS
+----------------
+
+In some other version control systems, you merge/update and then
+commit, with the risk of clobbering your changes with humongous
+conflicts. You shouldn't be pulling or merging if you haven't got
+your own work into good shape and committed it locally (see also
+linkgit:git-stash[1]).
+
+But novices can make this mistake, and 'git pull' and 'git merge'
+will stop without doing anything when local uncommitted changes
+overlap with files that 'git pull'/'git merge' may need to update.
+
+Also, to avoid unrelated changes in the recorded commit, 'git
+pull' and 'git merge' abort if there are any changes registered
+in the index relative to the contents of the `HEAD` commit.
+(One exception is when the changed index entries are already in
+the same state that would result from the merge anyway.)
+
+If all named commits are already ancestors of `HEAD`, 'git merge'
+will exit early with the message "Already up-to-date."
+
include::merge-strategies.txt[]
@@ -70,17 +92,9 @@ HOW MERGE WORKS
---------------
A merge is always between the current `HEAD` and one or more
-commits (usually, branch head or tag), and the index file must
-match the tree of `HEAD` commit (i.e. the contents of the last commit)
-when it starts out. In other words, `git diff --cached HEAD` must
-report no changes. (One exception is when the changed index
-entries are already in the same state that would result from
-the merge anyway.)
-
-Three kinds of merge can happen:
+commits (usually, branch head or tag).
-* The merged commit is already contained in `HEAD`. This is the
- simplest case, called "Already up-to-date."
+Two kinds of merge can happen:
* `HEAD` is already contained in the merged commit. This is the
most common case especially when invoked from 'git pull':
--
1.6.6
^ permalink raw reply related
* [PATCH 2/6] Documentation: merge: add an overview
From: Jonathan Nieder @ 2010-01-11 8:30 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Thomas Rast, Petr Baudis
In-Reply-To: <20100111082123.GA23742@progeny.tock>
The reader unfamiliar with the concepts of branching and merging
would have been completely lost. Try to help him with a diagram.
The diagram comes from the 'git rebase' manual page.
Cc: Petr Baudis <pasky@suse.cz>
Cc: Junio C Hamano <gitster@pobox.com>
Cc: Thomas Rast <trast@student.ethz.ch>,
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Does this tell enough of the story?
Documentation/git-merge.txt | 27 +++++++++++++++++++++++++--
1 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt
index 394ad0a..fe190e2 100644
--- a/Documentation/git-merge.txt
+++ b/Documentation/git-merge.txt
@@ -14,8 +14,31 @@ SYNOPSIS
DESCRIPTION
-----------
-This is the top-level interface to the merge machinery
-which drives multiple merge strategy scripts.
+Incorporates changes leading up to the named commits into the
+current branch. This command is used by 'git pull' to incorporate
+remote changes from another repository and may be used by hand to
+merge changes from one branch into another.
+
+Assume the following history exists and the current branch is
+"`master`":
+
+------------
+ A---B---C topic
+ /
+ D---E---F---G master
+------------
+
+Then "`git merge topic`" will apply the changes from `A`, `B`,
+and `C` to the work tree, and if they do not conflict with any
+changes from `master`, will store the result in a new commit along
+with the names of the two parent commits and a log message from the
+user describing the changes.
+
+------------
+ A---B---C topic
+ / \
+ D---E---F---G---H master
+------------
The second syntax (<msg> `HEAD` <remote>) is supported for
historical reasons. Do not use it from the command line or in
--
1.6.6
^ permalink raw reply related
* [PATCH/RFC 1/6] Documentation: clarify one-line description for merge
From: Jonathan Nieder @ 2010-01-11 8:27 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Thomas Rast, Petr Baudis
In-Reply-To: <20100111082123.GA23742@progeny.tock>
The 'git merge' command is generally not used to tie completely
independent projects together (though it can be used to do that)
but to reconcile branches of development that may have diverged.
Try to make this clearer in its one-line description.
Cc: Petr Baudis <pasky@suse.cz>
Cc: Junio C Hamano <gitster@pobox.com>
Cc: Thomas Rast <trast@student.ethz.ch>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
I am not sure this is an improvement at all. Mostly I wanted to
convey the idea of code forks being reconciled, but the resulting
phrase is not nearly as nice.
Documentation/git-merge.txt | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt
index e886c2e..394ad0a 100644
--- a/Documentation/git-merge.txt
+++ b/Documentation/git-merge.txt
@@ -3,8 +3,7 @@ git-merge(1)
NAME
----
-git-merge - Join two or more development histories together
-
+git-merge - Re-join diverging branches of development
SYNOPSIS
--------
--
1.6.6
^ permalink raw reply related
* [PATCH 0/6] Re: Documentation: warn prominently against merging with dirty trees
From: Jonathan Nieder @ 2010-01-11 8:21 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Thomas Rast, Petr Baudis, git
In-Reply-To: <20100111041318.GA9806@progeny.tock>
Jonathan Nieder wrote:
> Junio C Hamano wrote:
>> You need to be able to tell the two ways in which a "mergy" operation can
>> "fail" apart [*1*].
>
> Thanks for bringing this up. The manual does not emphasize that
> point at all, but it should.
Maybe something like this (patch 4) could help. This should pass
through Thomas’s tree to avoid conflicts with his other changes; but
of course, I would be glad to hear any thoughts you have before then.
Jonathan Nieder (6):
Documentation: clarify one-line description for merge
Documentation: merge: add an overview
Documentation: merge: move configuration section to the end
Documentation: emphasize when git merge terminates early
Documentation: merge: add a section about fast-forward
Documentation: merge: tweak HOW MERGE WORKS section
Documentation/git-merge.txt | 149 ++++++++++++++++++++++++++----------------
1 files changed, 92 insertions(+), 57 deletions(-)
^ permalink raw reply
* Re: How to check new commit availability without full fetch?
From: Junio C Hamano @ 2010-01-11 8:09 UTC (permalink / raw)
To: Robin Rosenberg; +Cc: SLONIK.AZ, Git Mailing List
In-Reply-To: <201001110831.28278.robin.rosenberg@dewire.com>
Robin Rosenberg <robin.rosenberg@dewire.com> writes:
> söndagen den 10 januari 2010 12.12.09 skrev Leo Razoumov:
>> Hi List,
>> I am trying to find a way to check availability of new commits
>> *before* doing fetch or pull. Unfortunately, neither fetch nor pull
>> take "--dry-run" option (unlike push)
>
> Fetch has --dry-run. It's a fairly new option. The drawback is that it
> still does the fetch, but it does not update the refs. If you re.run it
> again it'll be quicker.
Doesn't that worry us if it really is quicker?
If --dry-run doesn't update the refs, why do the objects that were
transferred by them not get asked the next time? There must be a bug
somewhere, but it is getting late already, so I'll leave it to experts in
the transfer area to figure it out...
^ permalink raw reply
* Re: How to check new commit availability without full fetch?
From: Robin Rosenberg @ 2010-01-11 7:31 UTC (permalink / raw)
To: SLONIK.AZ; +Cc: Git Mailing List
In-Reply-To: <ee2a733e1001100312j786108fct1b4c8abd0acc5afc@mail.gmail.com>
söndagen den 10 januari 2010 12.12.09 skrev Leo Razoumov:
> Hi List,
> I am trying to find a way to check availability of new commits
> *before* doing fetch or pull. Unfortunately, neither fetch nor pull
> take "--dry-run" option (unlike push)
Fetch has --dry-run. It's a fairly new option. The drawback is that it
still does the fetch, but it does not update the refs. If you re.run it
again it'll be quicker.
A faster option is to use ls-remote, but you'll have to parse the data
yourself and compare with your remote refs to see what refs has changed,
and that will not tell you /what/ the changes are.
-- robin
^ permalink raw reply
* Re: Unable to get "pretty" URL aliases working
From: Junio C Hamano @ 2010-01-11 7:59 UTC (permalink / raw)
To: Adam Nielsen; +Cc: git
In-Reply-To: <4B4ABDB5.9000203@uq.edu.au>
Adam Nielsen <adam.nielsen@uq.edu.au> writes:
> I'm attemping to learn Git but I've gotten stuck trying to configure a
> server to host my repositories.
> ...
> [url "ssh://myserver/path/to/repos/"]
> insteadOf myserver:
url.*.insteadOf is a configuration done on the _client_, i.e. the one that
you run "git clone", "git fetch", "git push", etc. on.
$ cat >>$HOME/.gitconfig <<\EOF
[url "ssh://myserver/path/to/repos/"]
insteadOf = myserver://
EOF
$ git clone myserver://project.git
In any case, "attempting to learn Git" doesn't mix well with use of
"insteadOf" to me. If you know /path/to/repos/project.git is what you
want to access, any "attempting to learn Git" person would do more
straight-forward "git clone ssh://myserver/path/to/repos/project.git", or
"git clone myserver:/path/to/repos/project.git" which is even better (it
is shorter to type and is a more natural form to spell ssh transport).
;-)
^ permalink raw reply
* Re: [PATCH 2/2] Use $(git rev-parse --show-toplevel) in cd_to_toplevel()
From: Junio C Hamano @ 2010-01-11 7:46 UTC (permalink / raw)
To: Steven Drake; +Cc: git
In-Reply-To: <alpine.LNX.2.00.1001112022190.8842@vqena.qenxr.bet.am>
Steven Drake <sdrake@xnet.co.nz> writes:
> as it gives the absolute (aka "physical") path of the toplevel directory
> and 'cd -P' is not supported by all shell implementations.
>
> See NetBSD PR/42168.
> http://www.netbsd.org/cgi-bin/query-pr-single.pl?number=42168
> ---
> This is a revision of my original patch after the input from Jonathan.
> ---
> git-sh-setup.sh | 18 ++++--------------
> 1 files changed, 4 insertions(+), 14 deletions(-)
The patch text may make sense (I haven't thought things through yet) but
please make sure your proposed commit log messages conform to the local
convention.
(1) We don't chop a sentence in the middle of the subject line and
continue the same sentence to the first line of the body of the
message;
(2) We don't indent the log message by one SP at the beginning of lines;
(3) Please avoid referring to external resource in the commit log message
whenever makes sense; the log should be understandable on its own.
Because the first paragraph of your message describes the issue the
patch addresses very well already, you don't need "See NetBSD..." and
URL. If you want to have them to help the reviewers, place such
reference after the three-dash line, just like you wrote "This is a
revision..." You would help reviewers even more if you added a
pointer to your earlier patch after that sentence;
(4) Sign your patch, before the three-dash line.
> diff --git a/git-sh-setup.sh b/git-sh-setup.sh
> index dfcb807..4ecc578 100755
> --- a/git-sh-setup.sh
> +++ b/git-sh-setup.sh
> @@ -120,20 +120,10 @@ is_bare_repository () {
> }
>
> cd_to_toplevel () {
> + cdup=$(git rev-parse --show-toplevel) && cd "$cdup" || {
Please line-break immediately after &&; it makes it easier to read in
general, and it would make "cd" stand out in this particular case, as it
is the most important part of this particular function.
Thanks.
^ permalink raw reply
* Re: Unable to get "pretty" URL aliases working
From: Johannes Sixt @ 2010-01-11 7:46 UTC (permalink / raw)
To: Adam Nielsen; +Cc: git
In-Reply-To: <4B4ABDB5.9000203@uq.edu.au>
Adam Nielsen schrieb:
> I would like to be able to do this:
>
> git clone ssh://myserver/project.git
> git push
>
> And have it work, but I keep getting errors about "/project.git" not
> existing in the root directory of my server. (Which is correct, they
> are stored elsewhere.)
This form of URL can only accept the absolute path to project.git on
myserver, eg.:
ssh://myserver/home/adam/project.git
-- Hannes
^ permalink raw reply
* [PATCH 2/2] Use $(git rev-parse --show-toplevel) in cd_to_toplevel()
From: Steven Drake @ 2010-01-11 7:23 UTC (permalink / raw)
To: git
In-Reply-To: <alpine.LNX.2.00.1001102016380.2560@vqena.qenxr.bet.am>
as it gives the absolute (aka "physical") path of the toplevel directory
and 'cd -P' is not supported by all shell implementations.
See NetBSD PR/42168.
http://www.netbsd.org/cgi-bin/query-pr-single.pl?number=42168
---
This is a revision of my original patch after the input from Jonathan.
---
git-sh-setup.sh | 18 ++++--------------
1 files changed, 4 insertions(+), 14 deletions(-)
diff --git a/git-sh-setup.sh b/git-sh-setup.sh
index dfcb807..4ecc578 100755
--- a/git-sh-setup.sh
+++ b/git-sh-setup.sh
@@ -120,20 +120,10 @@ is_bare_repository () {
}
cd_to_toplevel () {
- cdup=$(git rev-parse --show-cdup)
- if test ! -z "$cdup"
- then
- # The "-P" option says to follow "physical" directory
- # structure instead of following symbolic links. When cdup is
- # "../", this means following the ".." entry in the current
- # directory instead textually removing a symlink path element
- # from the PWD shell variable. The "-P" behavior is more
- # consistent with the C-style chdir used by most of Git.
- cd -P "$cdup" || {
- echo >&2 "Cannot chdir to $cdup, the toplevel of the working tree"
- exit 1
- }
- fi
+ cdup=$(git rev-parse --show-toplevel) && cd "$cdup" || {
+ echo >&2 "Cannot chdir to $cdup, the toplevel of the working tree"
+ exit 1
+ }
}
require_work_tree () {
--
1.6.4
^ permalink raw reply related
* Re: [PATCH] Display author and committer after "git commit"
From: Junio C Hamano @ 2010-01-11 7:28 UTC (permalink / raw)
To: Adam Megacz; +Cc: git
In-Reply-To: <xuu2fx6d9rzb.fsf_-_@nowhere.com>
Adam Megacz <adam@megacz.com> writes:
> Display author (name, email, date) and committer (name, email, date)
> after creating a new commit to ensure that the user is alerted in the
> event that they are set in an undesirable manner.
Too much clutter for too little gain, except for a very first few commits
in the repository.
Why isn't the "# Author:" and "# Committer:" information you see along
with "git status" output in the editor "git commit" gives you sufficient
if it is to avoid unconfigured/misconfigured names and e-mail addresses?
> This patch is not necessarily meant for inclusion verbatim;
> ...
> diff --git a/pretty.c b/pretty.c
> index 8f5bd1a..2458509 100644
> --- a/pretty.c
> +++ b/pretty.c
> @@ -1028,16 +1028,26 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
> int need_8bit_cte = context->need_8bit_cte;
>
> if (fmt == CMIT_FMT_USERFORMAT) {
> - format_commit_message(commit, user_format, sb, context);
> + format_commit_message(commit, user_format, sb, context);
Of course it isn't, with a change like this ;-)
Indentation damages aside, there is a lot more serious issue with this.
You added this cruft *unconditionally* to show_log(). Doesn't it mean
that you made format-patch *unusable*? Try:
git am your_patch.mbox
make install
for i in 1 2 3 4 5
do
git format-patch -1 --stdout >patch.mbox
git reset --hard HEAD^
git am patch.mbox
done
git show -s
and weep.
Have you checked --pretty=fuller, by the way?
^ permalink raw reply
* Re: [PATCH 2/2] Use $(git rev-parse --show-toplevel) in cd_to_toplevel()
From: Steven Drake @ 2010-01-11 7:12 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: git
In-Reply-To: <20100110101154.GA18138@progeny.tock>
On Sun, 10 Jan 2010, Jonathan Nieder wrote:
> Why not 'cdup=$(git rev-parse --show-toplevel) && cd "$cdup"'
> unconditionally? That would avoid having to look for the .git dir
> twice and would mirror setup_work_tree() a bit more closely.
Depends on what you think is the lesser of to evials, running
'git rev-parse' twice or preforming a cd when theres no need to, but after
looking at setup_work_tree() I agree with you and will send in a new patch.
--
Steven
^ permalink raw reply
* Re: How to check new commit availability without full fetch?
From: Junio C Hamano @ 2010-01-11 7:12 UTC (permalink / raw)
To: Michael Witten; +Cc: Git Mailing List
In-Reply-To: <b4087cc51001102129n5d5ac022s4f6f3ee9512eefd2@mail.gmail.com>
Michael Witten <mfwitten@gmail.com> writes:
> I suggest adding this kind of information to the fetch/pull (and I
> suppose push) documentation.
Sounds good. Pleaes make it so.
^ permalink raw reply
* Re: [PATCH] grep: do not do external grep on skip-worktree entries
From: Junio C Hamano @ 2010-01-11 6:39 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Miles Bader, Jeff King, Nguyen Thai Ngoc Duy, git
In-Reply-To: <alpine.LFD.2.00.1001040801290.3630@localhost.localdomain>
Linus Torvalds <torvalds@linux-foundation.org> writes:
> It doesn't matter. Since we do the line-by-line thing, the input is always
> so short that DFA vs NFA vs BM vs other-clever-search doesn't matter.
> There is no scaling - the grep buffer tends to be too small for the
> algorithm to matter.
>
> And the reason we do things line-by-line is that we need to then output
> things line-per-line.
Here is an experimental patch; first, some numbers (hot cache best of 5 runs).
(baseline -- builtin grep)
$ time git grep --no-ext-grep qwerty
drivers/char/keyboard.c: "qwertyuiop[]\r\000as"...
real 0m1.521s
user 0m1.260s
sys 0m0.256s
(baseline -- external grep)
$ time git grep --ext-grep qwerty
drivers/char/keyboard.c: "qwertyuiop[]\r\000as"...
real 0m0.773s
user 0m0.416s
sys 0m0.376s
(with experimental patch -- builtin grep)
$ time ../git.git/git grep --no-ext-grep qwerty
drivers/char/keyboard.c: "qwertyuiop[]\r\000as"...
real 0m0.692s
user 0m0.440s
sys 0m0.252s
The idea is to see the earliest location in the entire remainder of the
buffer the pattern(s) we are looking for first appears, and skip all the
lines before that point. For this optimization to be valid, we should not
be looking for anything complex (e.g. "find lines that have both X and Y
but not Z" is out). We cannot use the optimization when "-v" is given,
either, because then we need to find the first line that does _not_ match
given set of patterns.
---
grep.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 64 insertions(+), 0 deletions(-)
diff --git a/grep.c b/grep.c
index bdadf2c..940e200 100644
--- a/grep.c
+++ b/grep.c
@@ -615,6 +615,65 @@ static void show_pre_context(struct grep_opt *opt, const char *name, char *buf,
}
}
+static int should_lookahead(struct grep_opt *opt)
+{
+ struct grep_pat *p;
+
+ if (opt->extended)
+ return 0; /* punt for too complex stuff */
+ if (opt->invert || opt->unmatch_name_only)
+ return 0;
+ for (p = opt->pattern_list; p; p = p->next) {
+ if (p->token != GREP_PATTERN)
+ return 0; /* punt for "header only" and stuff */
+ }
+ return 1;
+}
+
+static int look_ahead(struct grep_opt *opt,
+ unsigned long *left_p,
+ unsigned *lno_p,
+ char **bol_p)
+{
+ unsigned lno = *lno_p;
+ char *bol = *bol_p;
+ struct grep_pat *p;
+ char *sp, *last_bol;
+ regoff_t earliest = -1;
+
+ for (p = opt->pattern_list; p; p = p->next) {
+ int hit;
+ regmatch_t m;
+
+ if (p->fixed)
+ hit = !fixmatch(p->pattern, bol, p->ignore_case, &m);
+ else
+ hit = !regexec(&p->regexp, bol, 1, &m, 0);
+ if (!hit || m.rm_so < 0 || m.rm_eo < 0)
+ continue;
+ if (earliest < 0 || m.rm_so < earliest)
+ earliest = m.rm_so;
+ }
+
+ if (earliest < 0) {
+ *bol_p = bol + *left_p;
+ *left_p = 0;
+ return 1;
+ }
+ for (sp = bol + earliest; bol < sp && sp[-1] != '\n'; sp--)
+ ; /* find the beginning of the line */
+ last_bol = sp;
+
+ for (sp = bol; sp < last_bol; sp++) {
+ if (*sp == '\n')
+ lno++;
+ }
+ *left_p -= last_bol - bol;
+ *bol_p = last_bol;
+ *lno_p = lno;
+ return 0;
+}
+
static int grep_buffer_1(struct grep_opt *opt, const char *name,
char *buf, unsigned long size, int collect_hits)
{
@@ -624,6 +683,7 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
unsigned last_hit = 0;
int binary_match_only = 0;
unsigned count = 0;
+ int try_lookahead = 0;
enum grep_context ctx = GREP_CONTEXT_HEAD;
xdemitconf_t xecfg;
@@ -652,11 +712,15 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
opt->priv = &xecfg;
}
}
+ try_lookahead = should_lookahead(opt);
while (left) {
char *eol, ch;
int hit;
+ if (try_lookahead
+ && look_ahead(opt, &left, &lno, &bol))
+ break;
eol = end_of_line(bol, &left);
ch = *eol;
*eol = 0;
^ permalink raw reply related
* Unable to get "pretty" URL aliases working
From: Adam Nielsen @ 2010-01-11 5:57 UTC (permalink / raw)
To: git
Hi all,
I'm attemping to learn Git but I've gotten stuck trying to configure a
server to host my repositories.
I would like to be able to do this:
git clone ssh://myserver/project.git
git push
And have it work, but I keep getting errors about "/project.git" not
existing in the root directory of my server. (Which is correct, they
are stored elsewhere.)
The only documentation I could find about mapping a deep path to a
"pretty" URL like this was in git-push(1) which stated I should add
something like the following to a "config file". I'm guessing it means
/etc/gitconfig on the server.
[url "ssh://myserver/path/to/repos/"]
insteadOf myserver:
I'm a bit confused about where the colon comes into it, if I use that on
the command line I get errors about resolving domain names. I've tried
many variations of the insteadOf line ("ssh://myserver/", "myserver:/",
"myserver/" etc.) but none of them make any difference. I don't even
know if this file is being used.
Any pointers about how this URL mapping can be set up?
Many thanks,
Adam.
(Please CC)
^ permalink raw reply
* Re: How to check new commit availability without full fetch?
From: Dmitry Potapov @ 2010-01-11 5:38 UTC (permalink / raw)
To: Leo Razoumov; +Cc: Nicolas Pitre, Junio C Hamano, Git Mailing List
In-Reply-To: <ee2a733e1001101736p2f395de6ka05044fe7cca624d@mail.gmail.com>
On Sun, Jan 10, 2010 at 08:36:44PM -0500, Leo Razoumov wrote:
>
> BTW, pull and push are in a way symmetric operations.
Not really... 'pull' = 'fetch' + 'merge', while 'push' only propagates
changes without any merging. You can say 'fetch' and 'push' are in a way
symmetric operations, but this symmetry is limited due to difference in
usage between local and remote branches.
> Is there any
> deep reason why push supports --dry-run but pull/fetch does not??
I guess it is because no one needs it. 'push' has --dry-run, because
it updates local references in a remote repository. So, you may want
to be sure that you are pushing the right thing. On the other hand,
I see no reason to have --dry-run for 'fetch', because it updates only
remote references, making them to point to the current state of the
corresponding branches. 'fetch' does not change any local branch, so
I see no reason for --dry-run.
What use case do you have in mind that needs --dry-run for 'fetch'?
Dmitry
^ permalink raw reply
* Re: How to check new commit availability without full fetch?
From: Michael Witten @ 2010-01-11 5:29 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List
In-Reply-To: <7vk4vpcs1q.fsf@alter.siamese.dyndns.org>
On Sun, Jan 10, 2010 at 8:08 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Until all the objects are safely transferred, none of the refs
> are updated, whether they are directly slurped into local branch namespace
> or remote tracking branch namespace. So no matter what the configuration
> is, interrupted transfer, forced or otherwise, is safe.
I suggest adding this kind of information to the fetch/pull (and I
suppose push) documentation.
^ permalink raw reply
* [PATCH] fast-import: tag may point to any object type
From: Dmitry Potapov @ 2010-01-11 5:02 UTC (permalink / raw)
To: git, git; +Cc: Dmitry Potapov, Junio C Hamano, Shawn O. Pearce
If you tried to export the official git repository, and then to import it
back then git-fast-import would die complaining that "Mark :1 not a commit".
Accordingly to a generated crash file, Mark 1 is not a commit but a blob,
which is pointed by junio-gpg-pub tag. Because git-tag allows to create such
tags, git-fast-import should import them.
Signed-off-by: Dmitry Potapov <dpotapov@gmail.com>
---
fast-import.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/fast-import.c b/fast-import.c
index cd87049..e99990d 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -2305,6 +2305,7 @@ static void parse_new_tag(void)
struct tag *t;
uintmax_t from_mark = 0;
unsigned char sha1[20];
+ enum object_type type = OBJ_COMMIT;
/* Obtain the new tag name from the rest of our command */
sp = strchr(command_buf.buf, ' ') + 1;
@@ -2329,8 +2330,7 @@ static void parse_new_tag(void)
struct object_entry *oe;
from_mark = strtoumax(from + 1, NULL, 10);
oe = find_mark(from_mark);
- if (oe->type != OBJ_COMMIT)
- die("Mark :%" PRIuMAX " not a commit", from_mark);
+ type = oe->type;
hashcpy(sha1, oe->sha1);
} else if (!get_sha1(from, sha1)) {
unsigned long size;
@@ -2362,7 +2362,7 @@ static void parse_new_tag(void)
"object %s\n"
"type %s\n"
"tag %s\n",
- sha1_to_hex(sha1), commit_type, t->name);
+ sha1_to_hex(sha1), typename(type), t->name);
if (tagger)
strbuf_addf(&new_data,
"tagger %s\n", tagger);
--
1.6.6
^ permalink raw reply related
* Re: [PATCH] Display author and committer after "git commit"
From: Adam Megacz @ 2010-01-11 4:53 UTC (permalink / raw)
To: git
In-Reply-To: <xuu2fx6d9rzb.fsf_-_@nowhere.com>
Adam Megacz <adam@megacz.com> writes:
> either taken from the working tree or else displayed to the user for
> sanity checking purposes. Since the author/committer information is
> immutable and not taken from the working tree,
s/working tree/index/g
Sorry,
- a
^ permalink raw reply
* [PATCH] Display author and committer after "git commit"
From: Adam Megacz @ 2010-01-11 4:37 UTC (permalink / raw)
To: git
In-Reply-To: <7vskagh9fg.fsf@alter.siamese.dyndns.org>
Display author (name, email, date) and committer (name, email, date)
after creating a new commit to ensure that the user is alerted in the
event that they are set in an undesirable manner.
This patch seeks to accomplish the following goal: all data included
in the commit which are sha1-protected (and therefore immutable) are
either taken from the working tree or else displayed to the user for
sanity checking purposes. Since the author/committer information is
immutable and not taken from the working tree, achieving the goal
above requires printing out the author/committer. The short window of
time after committing a patch and before propagating it is the last
opportunity to modify the data (by deleting and recreating the commit).
This patch is not necessarily meant for inclusion verbatim; it's more
of a starting point for discussion.
---
commit.h | 2 ++
log-tree.c | 15 +++++++++++++++
pretty.c | 23 ++++++++++++++++++-----
3 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/commit.h b/commit.h
index e5332ef..e4222b0 100644
--- a/commit.h
+++ b/commit.h
@@ -59,6 +59,8 @@ enum cmit_fmt {
CMIT_FMT_ONELINE,
CMIT_FMT_EMAIL,
CMIT_FMT_USERFORMAT,
+ CMIT_FMT_COMMITTER_AND_DATE,
+ CMIT_FMT_AUTHOR_AND_DATE,
CMIT_FMT_UNSPECIFIED,
};
diff --git a/log-tree.c b/log-tree.c
index 0fdf159..7b399b8 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -160,6 +160,20 @@ static void append_signoff(struct strbuf *sb, const char *signoff)
strbuf_addch(sb, '\n');
}
+static void append_metadata(struct strbuf *sb,
+ struct commit *commit,
+ const struct pretty_print_context *ctx)
+{
+
+ strbuf_addch(sb, '\n');
+ strbuf_addstr(sb, " Author: ");
+ pretty_print_commit(CMIT_FMT_AUTHOR_AND_DATE, commit, sb, ctx);
+
+ strbuf_addch(sb, '\n');
+ strbuf_addstr(sb, " Committer: ");
+ pretty_print_commit(CMIT_FMT_COMMITTER_AND_DATE, commit, sb, ctx);
+}
+
static unsigned int digits_in_number(unsigned int number)
{
unsigned int i = 10, result = 1;
@@ -414,6 +428,7 @@ void show_log(struct rev_info *opt)
ctx.reflog_info = opt->reflog_info;
pretty_print_commit(opt->commit_format, commit, &msgbuf, &ctx);
+ append_metadata(&msgbuf, commit, &ctx);
if (opt->add_signoff)
append_signoff(&msgbuf, opt->add_signoff);
if (opt->show_log_size) {
diff --git a/pretty.c b/pretty.c
index 8f5bd1a..2458509 100644
--- a/pretty.c
+++ b/pretty.c
@@ -1028,16 +1028,26 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
int need_8bit_cte = context->need_8bit_cte;
if (fmt == CMIT_FMT_USERFORMAT) {
- format_commit_message(commit, user_format, sb, context);
+ format_commit_message(commit, user_format, sb, context);
return;
}
+ if (fmt == CMIT_FMT_COMMITTER_AND_DATE) {
+ format_commit_message(commit, "%cn <%ce> %cd", sb, context);
+ return;
+ }
+ if (fmt == CMIT_FMT_AUTHOR_AND_DATE) {
+ format_commit_message(commit, "%an <%ae> %ad", sb, context);
+ return;
+ }
reencoded = reencode_commit_message(commit, &encoding);
if (reencoded) {
msg = reencoded;
}
- if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL)
+
+ if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL ||
+ fmt == CMIT_FMT_COMMITTER_AND_DATE || CMIT_FMT_AUTHOR_AND_DATE)
indent = 0;
/*
@@ -1078,12 +1088,14 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
context->after_subject, encoding, need_8bit_cte);
beginning_of_body = sb->len;
- if (fmt != CMIT_FMT_ONELINE)
+ if (fmt != CMIT_FMT_ONELINE &&
+ fmt != CMIT_FMT_COMMITTER_AND_DATE && fmt != CMIT_FMT_AUTHOR_AND_DATE)
pp_remainder(fmt, &msg, sb, indent);
strbuf_rtrim(sb);
/* Make sure there is an EOLN for the non-oneline case */
- if (fmt != CMIT_FMT_ONELINE)
+ if (fmt != CMIT_FMT_ONELINE &&
+ fmt != CMIT_FMT_COMMITTER_AND_DATE && fmt != CMIT_FMT_AUTHOR_AND_DATE)
strbuf_addch(sb, '\n');
/*
@@ -1094,7 +1106,8 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
if (fmt == CMIT_FMT_EMAIL && sb->len <= beginning_of_body)
strbuf_addch(sb, '\n');
- if (fmt != CMIT_FMT_ONELINE)
+ if (fmt != CMIT_FMT_ONELINE &&
+ fmt != CMIT_FMT_COMMITTER_AND_DATE && fmt != CMIT_FMT_AUTHOR_AND_DATE)
get_commit_notes(commit, sb, encoding,
NOTES_SHOW_HEADER | NOTES_INDENT);
--
1.6.4.4
^ permalink raw reply related
* Re: [PATCH v2 2/4] Documentation: warn prominently against merging with dirty trees
From: Jonathan Nieder @ 2010-01-11 4:13 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Thomas Rast, git
In-Reply-To: <7vzl4lbcfl.fsf@alter.siamese.dyndns.org>
Junio C Hamano wrote:
> Jonathan Nieder <jrnieder@gmail.com> writes:
>> Here is a scenario I worry about:
>>
>> Suppose I have a change to main.c staged, to add a feature that others
>> have discussed as well. After a short distraction, I return and run
>> ‘git pull’ to see what upstream has been working on.
>
> If your index is dirty, any "mergy" operation will refuse to work *before*
> touching anything, so you won't use "git reset --merge" to begin with.
Yes, that is true. And I was not worried about that.
As the git-merge manual explains:
| A merge is always between the current HEAD and one or more commits
| (usually, branch head or tag), and the index file must match the tree of
| HEAD commit (i.e. the contents of the last commit) when it starts out. In
| other words, git diff --cached HEAD must report no changes. (One exception
| is when the changed index entries are already in the same state that would
| result from the merge anyway.)
The potentially problematic scenario for "git reset --merge" is this
last one, where a changed index entry is already in the same state
that would result from the merge. Would a "git reset --merge" reset
the changed contents away?
> You are allowed to have local modifications only in your work tree.
> Furthermore, even git experts limit them to something they feel they can
> afford to lose and recreate easily if necessary.
Sadly, even a small change disappearing can be unnerving for an expert
and dangerous for a novice.
> You need to be able to tell the two ways in which a "mergy" operation can
> "fail" apart [*1*].
Thanks for bringing this up. The manual does not emphasize that
point at all, but it should.
Jonathan
^ permalink raw reply
* [PATCH] Remove empty directories when checking out a commit with fewer submodules
From: Peter Collingbourne @ 2010-01-11 2:59 UTC (permalink / raw)
To: git; +Cc: Peter Collingbourne
Change the unlink_entry function to use rmdir to remove submodule
directories. Currently we try to use unlink, which will never succeed.
Of course rmdir will only succeed for empty (i.e. not checked out)
submodule directories. Behaviour if a submodule is checked out stays
essentially the same: print a warning message and keep the submodule
directory.
Signed-off-by: Peter Collingbourne <peter@pcc.me.uk>
---
t/t7400-submodule-basic.sh | 9 +++++++++
unpack-trees.c | 12 ++++++++++--
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index a0cc99a..1a4dc5f 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -299,6 +299,15 @@ test_expect_success 'ls-files gracefully handles trailing slash' '
'
+test_expect_success 'moving to a commit without submodule does not leave empty dir' '
+ rm -rf init &&
+ mkdir init &&
+ git reset --hard &&
+ git checkout initial &&
+ test ! -d init &&
+ git checkout second
+'
+
test_expect_success 'submodule <invalid-path> warns' '
git submodule no-such-submodule 2> output.err &&
diff --git a/unpack-trees.c b/unpack-trees.c
index dd5999c..b69847d 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -61,8 +61,16 @@ static void unlink_entry(struct cache_entry *ce)
{
if (has_symlink_or_noent_leading_path(ce->name, ce_namelen(ce)))
return;
- if (unlink_or_warn(ce->name))
- return;
+ if (S_ISGITLINK(ce->ce_mode)) {
+ if (rmdir(ce->name)) {
+ warning("unable to rmdir %s: %s",
+ ce->name, strerror(errno));
+ return;
+ }
+ }
+ else
+ if (unlink_or_warn(ce->name))
+ return;
schedule_dir_for_removal(ce->name, ce_namelen(ce));
}
--
1.6.5
^ permalink raw reply related
* Re: [PATCH v2 2/4] Documentation: warn prominently against merging with dirty trees
From: Junio C Hamano @ 2010-01-11 2:30 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Junio C Hamano, Thomas Rast, git
In-Reply-To: <20100111021322.GA8480@progeny.tock>
Jonathan Nieder <jrnieder@gmail.com> writes:
> Here is a scenario I worry about:
>
> Suppose I have a change to main.c staged, to add a feature that others
> have discussed as well. After a short distraction, I return and run
> ‘git pull’ to see what upstream has been working on.
If your index is dirty, any "mergy" operation will refuse to work *before*
touching anything, so you won't use "git reset --merge" to begin with.
You are allowed to have local modifications only in your work tree.
Furthermore, even git experts limit them to something they feel they can
afford to lose and recreate easily if necessary. See for example:
http://thread.gmane.org/gmane.comp.version-control.git/15148/focus=15476
That is why I said:
Of course, the user needs to understand what he or she is doing (see
http://thread.gmane.org/gmane.comp.version-control.git/136166/focus=136171
for example). And that is one reason we (at least I) try to teach new
people to start working from a clean tree, until they get comfortable
working with mergy operations.
and that is why the archived article referenced above refers to
http://gitster.livejournal.com/29060.html
You need to be able to tell the two ways in which a "mergy" operation can
"fail" apart [*1*].
- One that stops before touching anything (either your index was dirty
and nothing happened, or your index was clean but you had local
modifications in your work tree). You do not run "git reset --merge",
for this one; and
- Another that goes ahead and results in conflicts. When you got these
conflicts, you can "reset --merge" them away.
[Footnote]
*1* Strictly speaking, the latter is not even a "failure"; it allowed you
to make progress, merging all the auto-mergeable parts without your help,
and only asking you to handle the remainder.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox