* [PATCH v5] Be more user-friendly when refusing to do something because of conflict.
From: Matthieu Moy @ 2010-01-07 18:10 UTC (permalink / raw)
To: git, gitster; +Cc: Matthieu Moy
In-Reply-To: <1262878552-4775-1-git-send-email-Matthieu.Moy@imag.fr>
Various commands refuse to run in the presence of conflicts (commit,
merge, pull, cherry-pick/revert). They all used to provide rough, and
inconsistant error messages.
A new variable advice.resolveconflict is introduced, and allows more
verbose messages, pointing the user to the appropriate solution.
For commit, the error message used to look like this:
$ git commit
foo.txt: needs merge
foo.txt: unmerged (c34a92682e0394bc0d6f4d4a67a8e2d32395c169)
foo.txt: unmerged (3afcd75de8de0bb5076942fcb17446be50451030)
foo.txt: unmerged (c9785d77b76dfe4fb038bf927ee518f6ae45ede4)
error: Error building trees
The "need merge" line is given by refresh_cache. We add the IN_PORCELAIN
option to make the output more consistant with the other porcelain
commands, and catch the error in return, to stop with a clean error
message. The next lines were displayed by a call to cache_tree_update(),
which is not reached anymore if we noticed the conflict.
The new output looks like:
U foo.txt
fatal: 'commit' is not possible because you have unmerged files.
Please, fix them up in the work tree, and then use 'git add/rm <file>' as
appropriate to mark resolution and make a commit, or use 'git commit -a'.
Pull is slightly modified to abort immediately if $GIT_DIR/MERGE_HEAD
exists instead of waiting for merge to complain.
The behavior of merge and the test-case are slightly modified to reflect
the usual flow: start with conflicts, fix them, and afterwards get rid of
MERGE_HEAD, with different error messages at each stage.
Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>
---
Ahem. *This* one passes the test-suite :-\. Sorry for not having ran it earlier.
Since the test for git-merge is changed a bit, I added the last
paragraph of the commit message.
Documentation/config.txt | 4 ++++
advice.c | 16 ++++++++++++++++
advice.h | 5 +++++
builtin-commit.c | 14 ++++++++++++--
builtin-merge.c | 19 ++++++++++++++-----
builtin-revert.c | 15 ++++++++++++++-
git-pull.sh | 25 +++++++++++++++++++++++--
t/t3030-merge-recursive.sh | 6 ++++--
t/t3501-revert-cherry-pick.sh | 2 +-
9 files changed, 93 insertions(+), 13 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 304eabb..8761411 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -130,6 +130,10 @@ advice.*::
Advice shown when linkgit:git-merge[1] refuses to
merge to avoid overwritting local changes.
Default: true.
+ resolveConflict::
+ Advices shown by various commands when conflicts
+ prevent the operation from being performed.
+ Default: true.
--
core.fileMode::
diff --git a/advice.c b/advice.c
index cb666ac..3309521 100644
--- a/advice.c
+++ b/advice.c
@@ -3,6 +3,7 @@
int advice_push_nonfastforward = 1;
int advice_status_hints = 1;
int advice_commit_before_merge = 1;
+int advice_resolve_conflict = 1;
static struct {
const char *name;
@@ -11,6 +12,7 @@ static struct {
{ "pushnonfastforward", &advice_push_nonfastforward },
{ "statushints", &advice_status_hints },
{ "commitbeforemerge", &advice_commit_before_merge },
+ { "resolveconflict", &advice_resolve_conflict },
};
int git_default_advice_config(const char *var, const char *value)
@@ -27,3 +29,17 @@ int git_default_advice_config(const char *var, const char *value)
return 0;
}
+
+void NORETURN die_resolve_conflict(const char *me)
+{
+ if (advice_resolve_conflict)
+ /*
+ * Message used both when 'git commit' fails and when
+ * other commands doing a merge do.
+ */
+ die("'%s' is not possible because you have unmerged files.\n"
+ "Please, fix them up in the work tree, and then use 'git add/rm <file>' as\n"
+ "appropriate to mark resolution and make a commit, or use 'git commit -a'.", me);
+ else
+ die("'%s' is not possible because you have unmerged files.", me);
+}
diff --git a/advice.h b/advice.h
index 3de5000..acd5fdd 100644
--- a/advice.h
+++ b/advice.h
@@ -1,10 +1,15 @@
#ifndef ADVICE_H
#define ADVICE_H
+#include "git-compat-util.h"
+
extern int advice_push_nonfastforward;
extern int advice_status_hints;
extern int advice_commit_before_merge;
+extern int advice_resolve_conflict;
int git_default_advice_config(const char *var, const char *value);
+extern void NORETURN die_resolve_conflict(const char *me);
+
#endif /* ADVICE_H */
diff --git a/builtin-commit.c b/builtin-commit.c
index 592b103..c56dca0 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -244,6 +244,16 @@ static void create_base_index(void)
exit(128); /* We've already reported the error, finish dying */
}
+static void refresh_cache_or_die(int refresh_flags)
+{
+ /*
+ * refresh_flags contains REFRESH_QUIET, so the only errors
+ * are for unmerged entries.
+ */
+ if (refresh_cache(refresh_flags | REFRESH_IN_PORCELAIN))
+ die_resolve_conflict("commit");
+}
+
static char *prepare_index(int argc, const char **argv, const char *prefix, int is_status)
{
int fd;
@@ -283,7 +293,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, int
if (all || (also && pathspec && *pathspec)) {
int fd = hold_locked_index(&index_lock, 1);
add_files_to_cache(also ? prefix : NULL, pathspec, 0);
- refresh_cache(refresh_flags);
+ refresh_cache_or_die(refresh_flags);
if (write_cache(fd, active_cache, active_nr) ||
close_lock_file(&index_lock))
die("unable to write new_index file");
@@ -302,7 +312,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, int
*/
if (!pathspec || !*pathspec) {
fd = hold_locked_index(&index_lock, 1);
- refresh_cache(refresh_flags);
+ refresh_cache_or_die(refresh_flags);
if (write_cache(fd, active_cache, active_nr) ||
commit_locked_index(&index_lock))
die("unable to write new_index file");
diff --git a/builtin-merge.c b/builtin-merge.c
index f1c84d7..79a35c3 100644
--- a/builtin-merge.c
+++ b/builtin-merge.c
@@ -847,11 +847,20 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
const char *best_strategy = NULL, *wt_strategy = NULL;
struct commit_list **remotes = &remoteheads;
- if (file_exists(git_path("MERGE_HEAD")))
- die("You have not concluded your merge. (MERGE_HEAD exists)");
- if (read_cache_unmerged())
- die("You are in the middle of a conflicted merge."
- " (index unmerged)");
+ if (read_cache_unmerged()) {
+ die_resolve_conflict("merge");
+ }
+ if (file_exists(git_path("MERGE_HEAD"))) {
+ /*
+ * There is no unmerged entry, don't advise 'git
+ * add/rm <file>', just 'git commit'.
+ */
+ if (advice_resolve_conflict)
+ die("You have not concluded your merge (MERGE_HEAD exists).\n"
+ "Please, commit your changes before you can merge.");
+ else
+ die("You have not concluded your merge (MERGE_HEAD exists).");
+ }
/*
* Check if we are _not_ on a detached HEAD, i.e. if there is a
diff --git a/builtin-revert.c b/builtin-revert.c
index 151aa6a..d14dde3 100644
--- a/builtin-revert.c
+++ b/builtin-revert.c
@@ -233,6 +233,19 @@ static struct tree *empty_tree(void)
return tree;
}
+static NORETURN void die_dirty_index(const char *me)
+{
+ if (read_cache_unmerged()) {
+ die_resolve_conflict(me);
+ } else {
+ if (advice_commit_before_merge)
+ die("Your local changes would be overwritten by %s.\n"
+ "Please, commit your changes or stash them to proceed.", me);
+ else
+ die("Your local changes would be overwritten by %s.\n", me);
+ }
+}
+
static int revert_or_cherry_pick(int argc, const char **argv)
{
unsigned char head[20];
@@ -269,7 +282,7 @@ static int revert_or_cherry_pick(int argc, const char **argv)
if (get_sha1("HEAD", head))
die ("You do not have a valid HEAD");
if (index_differs_from("HEAD", 0))
- die ("Dirty index: cannot %s", me);
+ die_dirty_index(me);
}
discard_cache();
diff --git a/git-pull.sh b/git-pull.sh
index 9e69ada..54ce0af 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -13,8 +13,29 @@ set_reflog_action "pull $*"
require_work_tree
cd_to_toplevel
-test -z "$(git ls-files -u)" ||
- die "You are in the middle of a conflicted merge."
+
+die_conflict () {
+ git diff-index --cached --name-status -r --ignore-submodules HEAD --
+ if [ $(git config --bool --get advice.resolveConflict || echo true) = "true" ]; then
+ die "Pull is not possible because you have unmerged files.
+Please, fix them up in the work tree, and then use 'git add/rm <file>'
+as appropriate to mark resolution, or use 'git commit -a'."
+ else
+ die "Pull is not possible because you have unmerged files."
+ fi
+}
+
+die_merge () {
+ if [ $(git config --bool --get advice.resolveConflict || echo true) = "true" ]; then
+ die "You have not concluded your merge (MERGE_HEAD exists).
+Please, commit your changes before you can merge."
+ else
+ die "You have not concluded your merge (MERGE_HEAD exists)."
+ fi
+}
+
+test -z "$(git ls-files -u)" || die_conflict
+test -f "$GIT_DIR/MERGE_HEAD" && die_merge
strategy_args= diffstat= no_commit= squash= no_ff= ff_only=
log_arg= verbosity=
diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh
index 9b3fa2b..9929f82 100755
--- a/t/t3030-merge-recursive.sh
+++ b/t/t3030-merge-recursive.sh
@@ -276,11 +276,13 @@ test_expect_success 'fail if the index has unresolved entries' '
test_must_fail git merge "$c5" &&
test_must_fail git merge "$c5" 2> out &&
+ grep "not possible because you have unmerged files" out &&
+ git add -u &&
+ test_must_fail git merge "$c5" 2> out &&
grep "You have not concluded your merge" out &&
rm -f .git/MERGE_HEAD &&
test_must_fail git merge "$c5" 2> out &&
- grep "You are in the middle of a conflicted merge" out
-
+ grep "Your local changes to .* would be overwritten by merge." out
'
test_expect_success 'merge-recursive remove conflict' '
diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh
index bb4cf00..7f85815 100755
--- a/t/t3501-revert-cherry-pick.sh
+++ b/t/t3501-revert-cherry-pick.sh
@@ -66,7 +66,7 @@ test_expect_success 'revert forbidden on dirty working tree' '
echo content >extra_file &&
git add extra_file &&
test_must_fail git revert HEAD 2>errors &&
- grep "Dirty index" errors
+ grep "Your local changes would be overwritten by " errors
'
--
1.6.6.198.g3c5474
^ permalink raw reply related
* Re: [PATCH 3/3] Add "ls", which is basically ls-files with user-friendly settings
From: Matthieu Moy @ 2010-01-07 18:12 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy; +Cc: git
In-Reply-To: <1262884076-12293-4-git-send-email-pclouds@gmail.com>
Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:
> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
You should put the "which is equivalent to "git ls-files --max-depth
1|column"" part of your cover letter here I think to make the patch
self-contained.
--
Matthieu Moy
http://www-verimag.imag.fr/~moy/
^ permalink raw reply
* merging two equivalent branches
From: David Reitter @ 2010-01-07 18:17 UTC (permalink / raw)
To: git
Hello,
I have a problem with my git project, resulting from an upstream branch beyond my control being rewritten.
Can I specify parents for a revision whose history is hidden from git-log?
Concretely, I need to merge two branches that represent different conversions of the same original CVS branch (with >100k revisions).
I've been working with converted branch B, but now we have a new branch A. Revisions A150 and B145 correspond to the same tree, but there is no common ancestor:
A1 -> A2 -> A3 -> .. -> A150 (A)
B1 -> B2 -> B3 -> .. -> B145 (B)
I have a published downstream branch C with my own changes that started somewhere from B and has occasionally merged new developments from B. I'd now like to switch it to A. Future development will show up on A and I'd like to be able to merge it into C when that happens.
Using "git-merge -s ours" does this job nicely so that I can pull further development from the remote branch into mine.
However, git-log follows both parents of the new merge commit and thus shows many redundant commits. This is OK from the logical perspective, but because I have used the "ours" merge strategy, we're guaranteed to have only one revisions in the final tree. Thus, I wouldn't want to see all these revisions in the resulting branch. Grafts/rewrites or git-replace would probably lead to the same issue, I reckon.
Thanks for your help.
^ permalink raw reply
* Re: merging two equivalent branches
From: Christian MICHON @ 2010-01-07 18:22 UTC (permalink / raw)
To: David Reitter; +Cc: git
In-Reply-To: <B0543B3C-C139-4BD3-B028-58B4DA132422@gmail.com>
On Thu, Jan 7, 2010 at 7:17 PM, David Reitter <david.reitter@gmail.com> wrote:
> Hello,
>
> I have a problem with my git project, resulting from an upstream branch beyond my control being rewritten.
>
> Can I specify parents for a revision whose history is hidden from git-log?
>
I recall asking a similar question in 2008, and the answer was to look
at "git graft" and use "git filter-branch" to recreate history.
My 2 cents
--
Christian
--
http://detaolb.sourceforge.net/, a linux distribution for Qemu with Git inside !
^ permalink raw reply
* Re: [PATCH] Documentation: do not advertise --all in git-pull(1)
From: Zing @ 2010-01-07 18:25 UTC (permalink / raw)
To: git
In-Reply-To: <a6112d286c5deeb4cc2ccfb1a90ff384440c1341.1262880109.git.trast@student.ethz.ch>
On Thu, 07 Jan 2010 17:09:33 +0100, Thomas Rast wrote:
> This one fixes the documentation problem, but I think there's a deeper
> misunderstanding. What did you hope to do with 'git pull --all'? I
> suspect most people on this list would take it to mean "fetch all
> branches from all remotes, and merge them into HEAD". I cannot imagine
> a use-case where that would make any sense. (And it wouldn't work,
> because the current implementation of 'git fetch --all' leaves only the
> last remote's branches in FETCH_HEAD.)
>
> From earlier discussions on the non-intuitiveness of git-pull, I kind of
> suspect you wanted to fetch all remotes, and then "update" all local
> branches that track some remote with their corresponding remote-tracking
> branches. In which case the question is: why do you use local branches
> if you have them "blindly" track the upstream?
Let me just state first that I'm a casual git user and I would have
missed those earlier discussions.... sorry if this old news:
I do basically just use git to just "blindly" track upstream repos/
projects using local branches. I realize this is "dumb" in a sense,
because it's basically just a copy of the remote branch that needs to be
fast-forwarded all the time; but it's just a handy lazy way for me to
remember which remote branches I want to "watch" with just a 'git branch'
command, plus it's easier and shorter to just type the local branch names
I specify than to type for example "origin/something" or "myotherremote/
something".
What I thought 'git pull --all' would do is just pass down the --all flag
to fetch and that's it:
1. do a 'git fetch --all'
2. then do a 'git merge <tracked remote branch of the current local
branch>', basically, in my case, just fast-forwarding my current local
branch if need be.
I didn't think that 'git pull --all' would "update" all local branches
that needed to be fast-forwarded. It would be too, how to say, "messy"
in the output, and not really what 'git pull' alone was doing before. I
did think it could be a possibility, so, really, I was trying it out to
see what would happen.
The other possibility you mentioned about fetching all branches and then
merging all of them to HEAD, didn't occur to me at all. I can see now
how it could make more intuitive sense from the perspective of a more
"experienced" git person. Personally, I don't think I'd ever need
something like that. HTH.
^ permalink raw reply
* Re: Difference between pull --rebase and fetch+rebase
From: martinvz @ 2010-01-07 18:44 UTC (permalink / raw)
To: git
In-Reply-To: <adf1fd3d1001070800k6fa501fej39b84f849b7e5b50@mail.gmail.com>
Thanks for your post, Santi. I can not share my repository since it is a
project at work. I was troubleshooting a bit myself and found the following
section in git-pull.sh:
oldremoteref="$(git rev-parse -q --verify "$remoteref")" &&
for reflog in $(git rev-list -g $remoteref 2>/dev/null)
do
if test "$reflog" = "$(git merge-base $reflog $curr_branch)"
then
oldremoteref="$reflog"
break
fi
done
Why is it that reflog entries are allowed to override the remote reference?
Thanks,
Martin
Santi Béjar-2 wrote:
>
> On Thu, Jan 7, 2010 at 1:23 PM, martinvz
> <martin.von.zweigbergk@gmail.com> wrote:
>>
>> I have a branch configured to track a remote branch by rebasing. I
>> excepted
>> that "git pull" would therefore be equivalent to fetching from the remote
>> repository followed by rebasing the remote branch, but it isn't. When
>> doing
>> "git rebase <remote>/<branch>", it applies only the commits after the
>> merge
>> base. When doing "git pull", it tries to apply two more commits (the two
>> commits preceding the merge base). Why is this?
>>
>> I get the same result even if I do "git pull --rebase <remote> <branch>",
>> it
>> doesn't seem to have anything to do with incorrect configuration of the
>> branch.
>
> Yes, both should do the same (at least when upstream is not rebased).
> Can you provide a test case or instructions to reproduce the behavior?
>
> Thanks,
> Santi
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
--
View this message in context: http://n2.nabble.com/Difference-between-pull-rebase-and-fetch-rebase-tp4266164p4268064.html
Sent from the git mailing list archive at Nabble.com.
^ permalink raw reply
* [PATCH] Add quiet option to git-ls-files
From: Ramkumar Ramachandra @ 2010-01-07 19:37 UTC (permalink / raw)
To: git
[-- Attachment #1: Type: text/plain, Size: 163 bytes --]
Hi,
I just wrote a couple of patches. I'm sorry for having to attach the
files- I'm behind a HTTP proxy, and Gmail mangles patches.
Thanks and regards,
Ramkumar
[-- Attachment #2: 0001-Add-quiet-option-to-git-ls-files.patch --]
[-- Type: text/x-patch, Size: 2284 bytes --]
From f5f76190a833bf105483a7da9b4b61ab03e373ba Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon@gmail.com>
Date: Thu, 7 Jan 2010 23:58:08 +0530
Subject: [PATCH 1/2] Add quiet option to git-ls-files
--quiet option suppresses error output in --error-unmatch mode. Modify
documentation to reflect changes.
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
Documentation/git-ls-files.txt | 6 ++++++
builtin-ls-files.c | 12 +++++++-----
2 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt
index 625723e..0a1f94e 100644
--- a/Documentation/git-ls-files.txt
+++ b/Documentation/git-ls-files.txt
@@ -82,6 +82,12 @@ OPTIONS
Skips files matching pattern.
Note that pattern is a shell wildcard pattern.
+--q::
+--quiet::
+ Only meaningful in --error-unmatch mode. Do not output an
+ error message if <file> does not appear in the index. Instead
+ exit with non-zero status silently.
+
-X <file>::
--exclude-from=<file>::
exclude patterns are read from <file>; 1 per line.
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index c9a03e5..40560da 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -421,12 +421,13 @@ static int option_parse_exclude_standard(const struct option *opt,
int cmd_ls_files(int argc, const char **argv, const char *prefix)
{
- int require_work_tree = 0, show_tag = 0;
+ int require_work_tree = 0, show_tag = 0, quiet = 0;
struct dir_struct dir;
struct option builtin_ls_files_options[] = {
{ OPTION_CALLBACK, 'z', NULL, NULL, NULL,
"paths are separated with NUL character",
PARSE_OPT_NOARG, option_parse_z },
+ OPT__QUIET(&quiet),
OPT_BOOLEAN('t', NULL, &show_tag,
"identify the file status with tags"),
OPT_BOOLEAN('v', NULL, &show_valid_bit,
@@ -547,10 +548,11 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
if (ps_matched) {
int bad;
- bad = report_path_error(ps_matched, pathspec, prefix_offset);
- if (bad)
- fprintf(stderr, "Did you forget to 'git add'?\n");
-
+ if (!quiet) {
+ bad = report_path_error(ps_matched, pathspec, prefix_offset);
+ if (bad)
+ fprintf(stderr, "Did you forget to 'git add'?\n");
+ }
return bad ? 1 : 0;
}
--
1.6.5
[-- Attachment #3: 0002-Replace-redirect-to-dev-null-in-favor-of-quiet-optio.patch --]
[-- Type: text/x-patch, Size: 3664 bytes --]
From b5c7a0fb8d092aafcedcbd653f00dee564a0d953 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon@gmail.com>
Date: Fri, 8 Jan 2010 00:00:58 +0530
Subject: [PATCH 2/2] Replace redirect to /dev/null in favor of quiet option
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
git-mergetool.sh | 2 +-
git-pull.sh | 2 +-
git-rebase.sh | 2 +-
git-stash.sh | 12 ++++++------
git-submodule.sh | 2 +-
5 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/git-mergetool.sh b/git-mergetool.sh
index b52a741..1c902aa 100755
--- a/git-mergetool.sh
+++ b/git-mergetool.sh
@@ -101,7 +101,7 @@ resolve_deleted_merge () {
return 0
;;
[dD]*)
- git rm -- "$MERGED" > /dev/null
+ git rm --quiet -- "$MERGED"
cleanup_temp_files
return 0
;;
diff --git a/git-pull.sh b/git-pull.sh
index 9e69ada..336e91a 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -170,7 +170,7 @@ test true = "$rebase" && {
. git-parse-remote &&
remoteref="$(get_remote_merge_branch "$@" 2>/dev/null)" &&
oldremoteref="$(git rev-parse -q --verify "$remoteref")" &&
- for reflog in $(git rev-list -g $remoteref 2>/dev/null)
+ for reflog in $(git rev-list --quiet --walk-reflogs $remoteref)
do
if test "$reflog" = "$(git merge-base $reflog $curr_branch)"
then
diff --git a/git-rebase.sh b/git-rebase.sh
index b121f45..bfe0475 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -100,7 +100,7 @@ call_merge () {
cmt="$(cat "$dotest/cmt.$1")"
echo "$cmt" > "$dotest/current"
hd=$(git rev-parse --verify HEAD)
- cmt_name=$(git symbolic-ref HEAD 2> /dev/null || echo HEAD)
+ cmt_name=$(git symbolic-ref --quiet HEAD || echo HEAD)
msgnum=$(cat "$dotest/msgnum")
end=$(cat "$dotest/end")
eval GITHEAD_$cmt='"${cmt_name##refs/heads/}~$(($end - $msgnum))"'
diff --git a/git-stash.sh b/git-stash.sh
index 3a0685f..5605d19 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -39,7 +39,7 @@ clear_stash () {
then
die "git stash clear with parameters is unimplemented"
fi
- if current=$(git rev-parse --verify $ref_stash 2>/dev/null)
+ if current=$(git rev-parse --quiet --verify $ref_stash)
then
git update-ref -d $ref_stash $current
fi
@@ -200,7 +200,7 @@ save_stash () {
}
have_stash () {
- git rev-parse --verify $ref_stash >/dev/null 2>&1
+ git rev-parse --quiet --verify $ref_stash >/dev/null
}
list_stash () {
@@ -337,16 +337,16 @@ drop_stash () {
fi
# Verify supplied argument looks like a stash entry
s=$(git rev-parse --verify "$@") &&
- git rev-parse --verify "$s:" > /dev/null 2>&1 &&
- git rev-parse --verify "$s^1:" > /dev/null 2>&1 &&
- git rev-parse --verify "$s^2:" > /dev/null 2>&1 ||
+ git rev-parse --quiet --verify "$s:" > /dev/null &&
+ git rev-parse --quiet --verify "$s^1:" > /dev/null &&
+ git rev-parse --quiet --verify "$s^2:" > /dev/null ||
die "$*: not a valid stashed state"
git reflog delete --updateref --rewrite "$@" &&
say "Dropped $* ($s)" || die "$*: Could not drop stash entry"
# clear_stash if we just dropped the last stash entry
- git rev-parse --verify "$ref_stash@{0}" > /dev/null 2>&1 || clear_stash
+ git rev-parse --quiet --verify "$ref_stash@{0}" > /dev/null || clear_stash
}
apply_to_branch () {
diff --git a/git-submodule.sh b/git-submodule.sh
index 77d2232..2b6448f 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -196,7 +196,7 @@ cmd_add()
tstart
s|/*$||
')
- git ls-files --error-unmatch "$path" > /dev/null 2>&1 &&
+ git ls-files --quiet --error-unmatch "$path" > /dev/null &&
die "'$path' already exists in the index"
# perhaps the path exists and is already a git repo, else clone it
--
1.6.5
^ permalink raw reply related
* Re: [PATCH] Add quiet option to git-ls-files
From: Junio C Hamano @ 2010-01-07 20:19 UTC (permalink / raw)
To: Ramkumar Ramachandra; +Cc: git
In-Reply-To: <f3271551001071137u6158fa4fm1bf7a51a83354574@mail.gmail.com>
Ramkumar Ramachandra <artagnon@gmail.com> writes:
> diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt
> index 625723e..0a1f94e 100644
> --- a/Documentation/git-ls-files.txt
> +++ b/Documentation/git-ls-files.txt
> @@ -82,6 +82,12 @@ OPTIONS
> Skips files matching pattern.
> Note that pattern is a shell wildcard pattern.
>
> +--q::
> +--quiet::
> + Only meaningful in --error-unmatch mode. Do not output an
> + error message if <file> does not appear in the index. Instead
> + exit with non-zero status silently.
The code doesn't seem to match the claim.
> diff --git a/builtin-ls-files.c b/builtin-ls-files.c
> index c9a03e5..40560da 100644
> --- a/builtin-ls-files.c
> +++ b/builtin-ls-files.c
> @@ -547,10 +548,11 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
>
> if (ps_matched) {
> int bad;
> + if (!quiet) {
> + bad = report_path_error(ps_matched, pathspec, prefix_offset);
> + if (bad)
> + fprintf(stderr, "Did you forget to 'git add'?\n");
> + }
> return bad ? 1 : 0;
> }
You might have seen that the code returns 1 during your testing, but that
is not because ps_matched[] was inspected, but because you are checking an
uninitialized garbage on stack in "bad" that happened to be non-zero.
^ permalink raw reply
* Re: [PATCH (v2) 2/2] rebase -i: teach --onto A...B syntax
From: Junio C Hamano @ 2010-01-07 20:19 UTC (permalink / raw)
To: Nanako Shiraishi; +Cc: Johannes Schindelin, git
In-Reply-To: <20100107200509.6117@nanako3.lavabit.com>
Nanako Shiraishi <nanako3@lavabit.com> writes:
> When rewriting commits on a topic branch, sometimes it is easier to
> compare the version of commits before and after the rewrite if they are
> based on the same commit that forked from the upstream. An earlier commit
> by Junio (fixed up by the previous commit) gives "--onto A...B" syntax to
> rebase command, and rebases on top of the merge base between A and B;
> teach the same to the interactive version, too.
>
> Signed-off-by: しらいし ななこ <nanako3@lavabit.com>
> ---
> git-rebase--interactive.sh | 21 ++++++++++++++++++++-
> t/t3415-rebase-onto-threedots.sh | 30 ++++++++++++++++++++++++++++++
> 2 files changed, 50 insertions(+), 1 deletions(-)
>
> diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
> index 23ded48..f7ae02c 100755
> --- a/git-rebase--interactive.sh
> +++ b/git-rebase--interactive.sh
> @@ -482,6 +482,25 @@ get_saved_options () {
> test -f "$DOTEST"/rebase-root && REBASE_ROOT=t
> }
>
> +LF='
> +'
> +parse_onto () {
> + case "$1" in
> + *...*)
> + if left=${1%...*} right=${1#*...} &&
> + onto=$(git merge-base --all ${left:-HEAD} ${right:-HEAD})
> + then
> + case "$onto" in
> + ?*"$LF"?* | '')
> + exit 1 ;;
> + esac
> + echo "$onto"
> + exit 0
> + fi
> + esac
> + git rev-parse --verify "$1^0"
> +}
> +
> while test $# != 0
> do
> case "$1" in
I am a bit unhappy about the duplication. The text of this function is
different from the one in "rebase" proper, but they implement essentially
the same logic. I was tempted to suggest having a common helper function,
but as Dscho mentioned "rebase -i" implementation does not share much with
"rebase" (even though it shares the external command line interface from
the end user's point of view), and I don't see a readily available place
(other than in git-sh-setup) to do so.
Ideas?
^ permalink raw reply
* Re: [NON-PATCH 3/2] Documentation/git-merge: format full commands in typewriter font
From: Jonathan Nieder @ 2010-01-07 20:25 UTC (permalink / raw)
To: Thomas Rast; +Cc: git, Junio C Hamano
In-Reply-To: <ebbb4e2b0e98490a64b3cd52c33d3a995fa7e980.1262883414.git.trast@student.ethz.ch>
Thomas Rast wrote:
> * More importantly, while `code` style seems to be an improvement in
> HTML output (because it gives typewriter font), my local 'man'
> renders 'emphasis' as underlines -- which actually makes the code
> snippets much more visible than `literal` quotes which are not
> rendered specially at all.
Maybe some point in the asciidoc/docbook-xsl/nroff chain could be
convinced to render `literal` quotes underlined on the console.
Jonathan
^ permalink raw reply
* Re: [NON-PATCH 3/2] Documentation/git-merge: format full commands in typewriter font
From: Junio C Hamano @ 2010-01-07 21:08 UTC (permalink / raw)
To: Thomas Rast; +Cc: git
In-Reply-To: <ebbb4e2b0e98490a64b3cd52c33d3a995fa7e980.1262883414.git.trast@student.ethz.ch>
Thomas Rast <trast@student.ethz.ch> writes:
> * More importantly, while `code` style seems to be an improvement in
> HTML output (because it gives typewriter font), my local 'man'
> renders 'emphasis' as underlines -- which actually makes the code
> snippets much more visible than `literal` quotes which are not
> rendered specially at all.
>
> So which way should it be changed?
I'd prefer to see us mark code as `code`.
The documentation toolchain may hopefully be fixed in the upstream in the
future, and we could keep our local style tweaks in Documentation/ until
that happens if we really wanted to.
^ permalink raw reply
* Re: [PATCH (v2) 2/2] rebase -i: teach --onto A...B syntax
From: Johannes Sixt @ 2010-01-07 21:10 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Nanako Shiraishi, Johannes Schindelin, git
In-Reply-To: <7vtyux3bx1.fsf@alter.siamese.dyndns.org>
On Donnerstag, 7. Januar 2010, Junio C Hamano wrote:
> I was tempted to suggest having a common helper function,
> but as Dscho mentioned "rebase -i" implementation does not share much with
> "rebase" (even though it shares the external command line interface from
> the end user's point of view), and I don't see a readily available place
> (other than in git-sh-setup) to do so.
>
> Ideas?
1. Split git-rebase--merge.sh and git-rebase--am.sh backends off of
git-rebase.sh. Have git-rebase.sh dispatch to
git-rebase--{am,merge,interactive}.sh as appropriate.
2. Unify command line parsing from git-rebase--*.sh in git-rebase.sh. The
git-rebase--*.sh can now simply refer to shell variables that were set by
command line switches (the backends must be invoked using the . (dot)
command).
3. Place common functionality like the one above in git-rebase.sh.
-- Hannes
^ permalink raw reply
* git-log - hide parent (was: merging two equivalent branches)
From: David Reitter @ 2010-01-07 21:16 UTC (permalink / raw)
To: git, Christian MICHON
In-Reply-To: <46d6db661001071022t79ca65foac249d948a20c328@mail.gmail.com>
On Jan 7, 2010, at 1:22 PM, Christian MICHON wrote:
> I recall asking a similar question in 2008, and the answer was to look
> at "git graft" and use "git filter-branch" to recreate history.
Thanks, I've tried that and I recall that filter-branch wasn't willing to rewrite just the recent history - at least in started going over all 100k revisions at a very slow pace.
I'm still unsure how, after the filter-branch, I would have some ancestor from the B series so that future pulls from the remote work, while having an ancestor from A, to make sure I can continue merging into C. If history is rewritten, I'll get new revisions and lose ancestors.
I'm beginning to thing that the cutting and pasting I'd like is conceptually impossible.
So what one would need is to specify a "silent parent" for a revision that is relevant w.r.t. future three-way merges, but indicates that the history behind the silent parent is irrelevant and shouldn't be shown in a git-log. The runaway parent would be guaranteed to _not_ contribute any content to the tree of the child revision, as is the case with a "merge ours".
This could be implemented as a way to mark a parent as silent (checked by git-log at least), but one could also allow for an empty commit that, while having a normal parent, clears out the tree.
Let me know if this idea is completely crazy.
^ permalink raw reply
* [PATCH] mingw: enable NO_PYTHON
From: Erik Faye-Lund @ 2010-01-07 21:52 UTC (permalink / raw)
To: msysgit; +Cc: git, Erik Faye-Lund
Python is not commonly installed on Windows machines, so
we should disable it there by default.
Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
---
This patch is against Junio's current master, and enables
msysgit to compile upstream git again after Sverre's addition
of the python remote-helpers (2fe40b6).
Makefile | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
index 1c7668a..a2780a2 100644
--- a/Makefile
+++ b/Makefile
@@ -1028,6 +1028,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
BLK_SHA1 = YesPlease
NO_INET_PTON = YesPlease
NO_INET_NTOP = YesPlease
+ NO_PYTHON = YesPlease
COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o
--
1.6.6.95.g82b1b.dirty
^ permalink raw reply related
* [PATCH 0/5] Miscellaneous improvements on Windows
From: Johannes Sixt @ 2010-01-07 21:54 UTC (permalink / raw)
To: msysgit; +Cc: git, Johannes Sixt
This series is actually a set of independent changes that improve
the Windows port. (Except that 2/5 depends on 1/5.)
1/5 and 2/5 enable threaded code on Windows. This topic was discussed
beginning of November. The change to builtin-pack-objects.c was
positively commented (though not formally acked) by Nico:
http://thread.gmane.org/gmane.comp.version-control.git/131998/focus=132239
3/5 removes a static dependency on shell32.dll so that startup time is
reduced. It does reduce the runtime of the test suite ('make -j2 test')
from 16:00min to 12:40min for me.
4/5 (the new pipe implementation) could be considered code churn.
It reduces LOC, but the effect is not noticable during run-time.
5/5 (avoid "dup dance") straightens our run-command implementation a
bit. It is more of the future-proofing kind because it avoids that a
writable pipe end remains accidentally open in a child process, leaving
the reader waiting idenfinetly. This doesn't seem to be a problem
currently, though.
I'm using these patches since November.
Andrzej K. Haczewski (1):
MSVC: Windows-native implementation for subset of Pthreads API
Johannes Sixt (4):
MinGW: enable pthreads
Windows: boost startup by avoiding a static dependency on shell32.dll
Windows: simplify the pipe(2) implementation
Windows: avoid the "dup dance" when spawning a child process
Makefile | 13 +++--
builtin-pack-objects.c | 31 +++++++++++--
compat/mingw.c | 80 ++++++++++++++++----------------
compat/mingw.h | 8 +++-
compat/win32/pthread.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++
compat/win32/pthread.h | 68 +++++++++++++++++++++++++++
run-command.c | 71 ++++++++++++----------------
7 files changed, 300 insertions(+), 91 deletions(-)
create mode 100644 compat/win32/pthread.c
create mode 100644 compat/win32/pthread.h
^ permalink raw reply
* [PATCH 1/5] MSVC: Windows-native implementation for subset of Pthreads API
From: Johannes Sixt @ 2010-01-07 21:54 UTC (permalink / raw)
To: msysgit; +Cc: git, Andrzej K. Haczewski, Johannes Sixt
In-Reply-To: <cover.1262895936.git.j6t@kdbg.org>
From: Andrzej K. Haczewski <ahaczewski@gmail.com>
This patch implements native to Windows subset of pthreads API used by Git.
It allows to remove Pthreads for Win32 dependency for MSVC, msysgit and
Cygwin.
The patch modifies Makefile only for MSVC (that's the environment I'm
capable of testing on), so it requires further corrections to compile
with MinGW or Cygwin.
Signed-off-by: Andrzej K. Haczewski <ahaczewski@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
---
Makefile | 7 ++-
builtin-pack-objects.c | 31 +++++++++++--
compat/mingw.c | 2 +-
compat/mingw.h | 5 ++
compat/win32/pthread.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++
compat/win32/pthread.h | 68 +++++++++++++++++++++++++++
6 files changed, 225 insertions(+), 8 deletions(-)
create mode 100644 compat/win32/pthread.c
create mode 100644 compat/win32/pthread.h
diff --git a/Makefile b/Makefile
index 4a1e5bc..ed547d9 100644
--- a/Makefile
+++ b/Makefile
@@ -451,6 +451,7 @@ LIB_H += commit.h
LIB_H += compat/bswap.h
LIB_H += compat/cygwin.h
LIB_H += compat/mingw.h
+LIB_H += compat/win32/pthread.h
LIB_H += csum-file.h
LIB_H += decorate.h
LIB_H += delta.h
@@ -967,15 +968,15 @@ ifeq ($(uname_S),Windows)
OBJECT_CREATION_USES_RENAMES = UnfortunatelyNeedsTo
NO_REGEX = YesPlease
NO_CURL = YesPlease
- NO_PTHREADS = YesPlease
+ THREADED_DELTA_SEARCH = YesPlease
BLK_SHA1 = YesPlease
CC = compat/vcbuild/scripts/clink.pl
AR = compat/vcbuild/scripts/lib.pl
CFLAGS =
BASIC_CFLAGS = -nologo -I. -I../zlib -Icompat/vcbuild -Icompat/vcbuild/include -DWIN32 -D_CONSOLE -DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE
- COMPAT_OBJS = compat/msvc.o compat/fnmatch/fnmatch.o compat/winansi.o
- COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/fnmatch -Icompat/regex -Icompat/fnmatch -DSTRIP_EXTENSION=\".exe\"
+ COMPAT_OBJS = compat/msvc.o compat/fnmatch/fnmatch.o compat/winansi.o compat/win32/pthread.o
+ COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/fnmatch -Icompat/regex -Icompat/fnmatch -Icompat/win32 -DSTRIP_EXTENSION=\".exe\"
BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -SUBSYSTEM:CONSOLE -NODEFAULTLIB:MSVCRT.lib
EXTLIBS = advapi32.lib shell32.lib wininet.lib ws2_32.lib
lib =
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 4429d53..2fdabaa 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -1256,15 +1256,15 @@ static int delta_cacheable(unsigned long src_size, unsigned long trg_size,
#ifdef THREADED_DELTA_SEARCH
-static pthread_mutex_t read_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t read_mutex;
#define read_lock() pthread_mutex_lock(&read_mutex)
#define read_unlock() pthread_mutex_unlock(&read_mutex)
-static pthread_mutex_t cache_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t cache_mutex;
#define cache_lock() pthread_mutex_lock(&cache_mutex)
#define cache_unlock() pthread_mutex_unlock(&cache_mutex)
-static pthread_mutex_t progress_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t progress_mutex;
#define progress_lock() pthread_mutex_lock(&progress_mutex)
#define progress_unlock() pthread_mutex_unlock(&progress_mutex)
@@ -1591,7 +1591,26 @@ struct thread_params {
unsigned *processed;
};
-static pthread_cond_t progress_cond = PTHREAD_COND_INITIALIZER;
+static pthread_cond_t progress_cond;
+
+/*
+ * Mutex and conditional variable can't be statically-initialized on Windows.
+ */
+static void init_threaded_search()
+{
+ pthread_mutex_init(&read_mutex, NULL);
+ pthread_mutex_init(&cache_mutex, NULL);
+ pthread_mutex_init(&progress_mutex, NULL);
+ pthread_cond_init(&progress_cond, NULL);
+}
+
+static void cleanup_threaded_search()
+{
+ pthread_cond_destroy(&progress_cond);
+ pthread_mutex_destroy(&read_mutex);
+ pthread_mutex_destroy(&cache_mutex);
+ pthread_mutex_destroy(&progress_mutex);
+}
static void *threaded_find_deltas(void *arg)
{
@@ -1630,10 +1649,13 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size,
struct thread_params *p;
int i, ret, active_threads = 0;
+ init_threaded_search();
+
if (!delta_search_threads) /* --threads=0 means autodetect */
delta_search_threads = online_cpus();
if (delta_search_threads <= 1) {
find_deltas(list, &list_size, window, depth, processed);
+ cleanup_threaded_search();
return;
}
if (progress > pack_to_stdout)
@@ -1748,6 +1770,7 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size,
active_threads--;
}
}
+ cleanup_threaded_search();
free(p);
}
diff --git a/compat/mingw.c b/compat/mingw.c
index 0d73f15..bc3dc74 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -5,7 +5,7 @@
#include <shellapi.h>
-static int err_win_to_posix(DWORD winerr)
+int err_win_to_posix(DWORD winerr)
{
int error = ENOSYS;
switch(winerr) {
diff --git a/compat/mingw.h b/compat/mingw.h
index b3d299f..e681135 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -307,3 +307,8 @@ struct mingw_dirent
#define readdir(x) mingw_readdir(x)
struct dirent *mingw_readdir(DIR *dir);
#endif // !NO_MINGW_REPLACE_READDIR
+
+/*
+ * Used by Pthread API implementation for Windows
+ */
+extern int err_win_to_posix(DWORD winerr);
diff --git a/compat/win32/pthread.c b/compat/win32/pthread.c
new file mode 100644
index 0000000..652d7b4
--- /dev/null
+++ b/compat/win32/pthread.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2009 Andrzej K. Haczewski <ahaczewski@gmail.com>
+ *
+ * DISCLAMER: The implementation is Git-specific, it is subset of original
+ * Pthreads API, without lots of other features that Git doesn't use.
+ * Git also makes sure that the passed arguments are valid, so there's
+ * no need for double-checking.
+ */
+
+#include "../../git-compat-util.h"
+#include "pthread.h"
+
+#include <errno.h>
+#include <limits.h>
+
+static unsigned __stdcall win32_start_routine(void *arg)
+{
+ pthread_t *thread = arg;
+ thread->arg = thread->start_routine(thread->arg);
+ return 0;
+}
+
+int pthread_create(pthread_t *thread, const void *unused,
+ void *(*start_routine)(void*), void *arg)
+{
+ thread->arg = arg;
+ thread->start_routine = start_routine;
+ thread->handle = (HANDLE)
+ _beginthreadex(NULL, 0, win32_start_routine, thread, 0, NULL);
+
+ if (!thread->handle)
+ return errno;
+ else
+ return 0;
+}
+
+int win32_pthread_join(pthread_t *thread, void **value_ptr)
+{
+ DWORD result = WaitForSingleObject(thread->handle, INFINITE);
+ switch (result) {
+ case WAIT_OBJECT_0:
+ if (value_ptr)
+ *value_ptr = thread->arg;
+ return 0;
+ case WAIT_ABANDONED:
+ return EINVAL;
+ default:
+ return err_win_to_posix(GetLastError());
+ }
+}
+
+int pthread_cond_init(pthread_cond_t *cond, const void *unused)
+{
+ cond->waiters = 0;
+
+ InitializeCriticalSection(&cond->waiters_lock);
+
+ cond->sema = CreateSemaphore(NULL, 0, LONG_MAX, NULL);
+ if (!cond->sema)
+ die("CreateSemaphore() failed");
+ return 0;
+}
+
+int pthread_cond_destroy(pthread_cond_t *cond)
+{
+ CloseHandle(cond->sema);
+ cond->sema = NULL;
+
+ DeleteCriticalSection(&cond->waiters_lock);
+
+ return 0;
+}
+
+int pthread_cond_wait(pthread_cond_t *cond, CRITICAL_SECTION *mutex)
+{
+ /* serialize access to waiters count */
+ EnterCriticalSection(&cond->waiters_lock);
+ ++cond->waiters;
+ LeaveCriticalSection(&cond->waiters_lock);
+
+ /*
+ * Unlock external mutex and wait for signal.
+ * NOTE: we've held mutex locked long enough to increment
+ * waiters count above, so there's no problem with
+ * leaving mutex unlocked before we wait on semaphore.
+ */
+ LeaveCriticalSection(mutex);
+
+ /* let's wait - ignore return value */
+ WaitForSingleObject(cond->sema, INFINITE);
+
+ /* we're done waiting, so make sure we decrease waiters count */
+ EnterCriticalSection(&cond->waiters_lock);
+ --cond->waiters;
+ LeaveCriticalSection(&cond->waiters_lock);
+
+ /* lock external mutex again */
+ EnterCriticalSection(mutex);
+
+ return 0;
+}
+
+int pthread_cond_signal(pthread_cond_t *cond)
+{
+ int have_waiters;
+
+ /* serialize access to waiters count */
+ EnterCriticalSection(&cond->waiters_lock);
+ have_waiters = cond->waiters > 0;
+ LeaveCriticalSection(&cond->waiters_lock);
+
+ /*
+ * Signal only when there are waiters
+ */
+ if (have_waiters)
+ return ReleaseSemaphore(cond->sema, 1, NULL) ?
+ 0 : err_win_to_posix(GetLastError());
+ else
+ return 0;
+}
diff --git a/compat/win32/pthread.h b/compat/win32/pthread.h
new file mode 100644
index 0000000..47888e4
--- /dev/null
+++ b/compat/win32/pthread.h
@@ -0,0 +1,68 @@
+/*
+ * Header used to adapt pthread-based POSIX code to Windows API threads.
+ *
+ * Copyright (C) 2009 Andrzej K. Haczewski <ahaczewski@gmail.com>
+ */
+
+#ifndef PTHREAD_H
+#define PTHREAD_H
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+
+#include <windows.h>
+
+/*
+ * Defines that adapt Windows API threads to pthreads API
+ */
+#define pthread_mutex_t CRITICAL_SECTION
+
+#define pthread_mutex_init(a,b) InitializeCriticalSection((a))
+#define pthread_mutex_destroy(a) DeleteCriticalSection((a))
+#define pthread_mutex_lock EnterCriticalSection
+#define pthread_mutex_unlock LeaveCriticalSection
+
+/*
+ * Implement simple condition variable for Windows threads, based on ACE
+ * implementation.
+ *
+ * See original implementation: http://bit.ly/1vkDjo
+ * ACE homepage: http://www.cse.wustl.edu/~schmidt/ACE.html
+ * See also: http://www.cse.wustl.edu/~schmidt/win32-cv-1.html
+ */
+typedef struct {
+ LONG waiters;
+ CRITICAL_SECTION waiters_lock;
+ HANDLE sema;
+} pthread_cond_t;
+
+extern int pthread_cond_init(pthread_cond_t *cond, const void *unused);
+
+extern int pthread_cond_destroy(pthread_cond_t *cond);
+
+extern int pthread_cond_wait(pthread_cond_t *cond, CRITICAL_SECTION *mutex);
+
+extern int pthread_cond_signal(pthread_cond_t *cond);
+
+/*
+ * Simple thread creation implementation using pthread API
+ */
+typedef struct {
+ HANDLE handle;
+ void *(*start_routine)(void*);
+ void *arg;
+} pthread_t;
+
+extern int pthread_create(pthread_t *thread, const void *unused,
+ void *(*start_routine)(void*), void *arg);
+
+/*
+ * To avoid the need of copying a struct, we use small macro wrapper to pass
+ * pointer to win32_pthread_join instead.
+ */
+#define pthread_join(a, b) win32_pthread_join(&(a), (b))
+
+extern int win32_pthread_join(pthread_t *thread, void **value_ptr);
+
+#endif /* PTHREAD_H */
--
1.6.6.115.gd1ab3
^ permalink raw reply related
* [PATCH 2/5] MinGW: enable pthreads
From: Johannes Sixt @ 2010-01-07 21:54 UTC (permalink / raw)
To: msysgit; +Cc: git, Johannes Sixt
In-Reply-To: <cover.1262895936.git.j6t@kdbg.org>
If the MinGW build was built as part of the msysgit build environment,
then threading was already enabled because the pthreads-win32 package
is available in msysgit.
The previous patch added a minimal pthreads implementation for Windows.
Therefore, we can now enable code that uses pthreads unconditionally.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
---
Makefile | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/Makefile b/Makefile
index ed547d9..087c3fa 100644
--- a/Makefile
+++ b/Makefile
@@ -1019,9 +1019,11 @@ ifneq (,$(findstring MINGW,$(uname_S)))
OBJECT_CREATION_USES_RENAMES = UnfortunatelyNeedsTo
NO_REGEX = YesPlease
BLK_SHA1 = YesPlease
+ THREADED_DELTA_SEARCH = YesPlease
COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
- COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o
+ COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o \
+ compat/win32/pthread.o
EXTLIBS += -lws2_32
X = .exe
ifneq (,$(wildcard ../THIS_IS_MSYSGIT))
@@ -1031,10 +1033,8 @@ ifneq (,$(wildcard ../THIS_IS_MSYSGIT))
EXTLIBS += /mingw/lib/libz.a
NO_R_TO_GCC_LINKER = YesPlease
INTERNAL_QSORT = YesPlease
- THREADED_DELTA_SEARCH = YesPlease
else
NO_CURL = YesPlease
- NO_PTHREADS = YesPlease
endif
endif
--
1.6.6.115.gd1ab3
^ permalink raw reply related
* [PATCH 3/5] Windows: boost startup by avoiding a static dependency on shell32.dll
From: Johannes Sixt @ 2010-01-07 21:54 UTC (permalink / raw)
To: msysgit; +Cc: git, Johannes Sixt
In-Reply-To: <cover.1262895936.git.j6t@kdbg.org>
This DLL is only needed to invoke the browser in a "git help" call. By
looking up the only function that we need at runtime, we can avoid the
startup costs of this DLL.
DLL usage can be profiled with Microsoft's Dependency Walker. For example,
a call to "git diff-files" loaded
before: 19 DLLs
after: 9 DLLs
(The results depend on the OS; this is on Windows XP SP3.)
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
---
compat/mingw.c | 16 ++++++++++++++--
1 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/compat/mingw.c b/compat/mingw.c
index bc3dc74..dfb1f05 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -3,8 +3,6 @@
#include <conio.h>
#include "../strbuf.h"
-#include <shellapi.h>
-
int err_win_to_posix(DWORD winerr)
{
int error = ENOSYS;
@@ -1338,8 +1336,22 @@ static const char *make_backslash_path(const char *path)
void mingw_open_html(const char *unixpath)
{
const char *htmlpath = make_backslash_path(unixpath);
+ typedef HINSTANCE (WINAPI *T)(HWND, const char *,
+ const char *, const char *, const char *, INT);
+ T ShellExecute;
+ HMODULE shell32;
+
+ shell32 = LoadLibrary("shell32.dll");
+ if (!shell32)
+ die("cannot load shell32.dll");
+ ShellExecute = (T)GetProcAddress(shell32, "ShellExecuteA");
+ if (!ShellExecute)
+ die("cannot run browser");
+
printf("Launching default browser to display HTML ...\n");
ShellExecute(NULL, "open", htmlpath, NULL, "\\", 0);
+
+ FreeLibrary(shell32);
}
int link(const char *oldpath, const char *newpath)
--
1.6.6.115.gd1ab3
^ permalink raw reply related
* [PATCH 4/5] Windows: simplify the pipe(2) implementation
From: Johannes Sixt @ 2010-01-07 21:55 UTC (permalink / raw)
To: msysgit; +Cc: git, Johannes Sixt
In-Reply-To: <cover.1262895936.git.j6t@kdbg.org>
Our implementation of pipe() must create non-inheritable handles for the
reason that when a child process is started, there is no opportunity to
close the unneeded pipe ends in the child (on POSIX this is done between
fork() and exec()).
Previously, we used the _pipe() function provided by Microsoft's C runtime
(which creates inheritable handles) and then turned the handles into
non-inheritable handles using the DuplicateHandle() API.
Simplify the procedure by using the CreatePipe() API, which can create
non-inheritable handles right from the beginning.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
---
compat/mingw.c | 37 ++++++++-----------------------------
1 files changed, 8 insertions(+), 29 deletions(-)
diff --git a/compat/mingw.c b/compat/mingw.c
index dfb1f05..9f4fab3 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -299,46 +299,25 @@ int gettimeofday(struct timeval *tv, void *tz)
int pipe(int filedes[2])
{
- int fd;
- HANDLE h[2], parent;
-
- if (_pipe(filedes, 8192, 0) < 0)
- return -1;
+ HANDLE h[2];
- parent = GetCurrentProcess();
-
- if (!DuplicateHandle (parent, (HANDLE)_get_osfhandle(filedes[0]),
- parent, &h[0], 0, FALSE, DUPLICATE_SAME_ACCESS)) {
- close(filedes[0]);
- close(filedes[1]);
- return -1;
- }
- if (!DuplicateHandle (parent, (HANDLE)_get_osfhandle(filedes[1]),
- parent, &h[1], 0, FALSE, DUPLICATE_SAME_ACCESS)) {
- close(filedes[0]);
- close(filedes[1]);
- CloseHandle(h[0]);
+ /* this creates non-inheritable handles */
+ if (!CreatePipe(&h[0], &h[1], NULL, 8192)) {
+ errno = err_win_to_posix(GetLastError());
return -1;
}
- fd = _open_osfhandle((int)h[0], O_NOINHERIT);
- if (fd < 0) {
- close(filedes[0]);
- close(filedes[1]);
+ filedes[0] = _open_osfhandle((int)h[0], O_NOINHERIT);
+ if (filedes[0] < 0) {
CloseHandle(h[0]);
CloseHandle(h[1]);
return -1;
}
- close(filedes[0]);
- filedes[0] = fd;
- fd = _open_osfhandle((int)h[1], O_NOINHERIT);
- if (fd < 0) {
+ filedes[1] = _open_osfhandle((int)h[1], O_NOINHERIT);
+ if (filedes[0] < 0) {
close(filedes[0]);
- close(filedes[1]);
CloseHandle(h[1]);
return -1;
}
- close(filedes[1]);
- filedes[1] = fd;
return 0;
}
--
1.6.6.115.gd1ab3
^ permalink raw reply related
* [PATCH 5/5] Windows: avoid the "dup dance" when spawning a child process
From: Johannes Sixt @ 2010-01-07 21:55 UTC (permalink / raw)
To: msysgit; +Cc: git, Johannes Sixt
In-Reply-To: <cover.1262895936.git.j6t@kdbg.org>
When stdin, stdout, or stderr must be redirected for a child process that
on Windows is spawned using one of the spawn() functions of Microsoft's
C runtime, then there is no choice other than to
1. make a backup copy of fd 0,1,2 with dup
2. dup2 the redirection source fd into 0,1,2
3. spawn
4. dup2 the backup back into 0,1,2
5. close the backup copy and the redirection source
We used this idiom as well -- but we are not using the spawn() functions!
Instead, we have our own implementation (originally, because we have to
override the environment, too). We had hardcoded that stdin, stdout, and
stderr of the child process were inherited from the parent's fds 0, 1,
and 2. But we can actually specify any fd.
With this patch, the fds to inherit are passed from start_command()'s
WIN32 section to our spawn implementation. This way, we can avoid the
backup copies of the fds.
The backup copies were a bug waiting to surface: The OS handles underlying
the dup()ed fds were inherited by the child process (but were not
associated with a file descriptor in the child). Consequently, the file or
pipe represented by the OS handle remained open even after the backup copy
was closed in the parent process.
Since our implementation of pipe() creates non-inheritable OS handles, we
still dup()s file descriptors in start_command() because dup() happens to
create inheritable duplicates. (A nice side effect is that the fd cleanup
in start_command is the same for Windows and Unix and remains unchanged.)
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
---
compat/mingw.c | 25 +++++++++++++------
compat/mingw.h | 3 +-
run-command.c | 71 ++++++++++++++++++++++++-------------------------------
3 files changed, 50 insertions(+), 49 deletions(-)
diff --git a/compat/mingw.c b/compat/mingw.c
index 9f4fab3..74ffc18 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -615,8 +615,8 @@ static int env_compare(const void *a, const void *b)
return strcasecmp(*ea, *eb);
}
-static pid_t mingw_spawnve(const char *cmd, const char **argv, char **env,
- int prepend_cmd)
+static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env,
+ int prepend_cmd, int fhin, int fhout, int fherr)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
@@ -652,9 +652,9 @@ static pid_t mingw_spawnve(const char *cmd, const char **argv, char **env,
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
- si.hStdInput = (HANDLE) _get_osfhandle(0);
- si.hStdOutput = (HANDLE) _get_osfhandle(1);
- si.hStdError = (HANDLE) _get_osfhandle(2);
+ si.hStdInput = (HANDLE) _get_osfhandle(fhin);
+ si.hStdOutput = (HANDLE) _get_osfhandle(fhout);
+ si.hStdError = (HANDLE) _get_osfhandle(fherr);
/* concatenate argv, quoting args as we go */
strbuf_init(&args, 0);
@@ -709,7 +709,14 @@ static pid_t mingw_spawnve(const char *cmd, const char **argv, char **env,
return (pid_t)pi.hProcess;
}
-pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env)
+static pid_t mingw_spawnve(const char *cmd, const char **argv, char **env,
+ int prepend_cmd)
+{
+ return mingw_spawnve_fd(cmd, argv, env, prepend_cmd, 0, 1, 2);
+}
+
+pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env,
+ int fhin, int fhout, int fherr)
{
pid_t pid;
char **path = get_path_split();
@@ -731,13 +738,15 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env)
pid = -1;
}
else {
- pid = mingw_spawnve(iprog, argv, env, 1);
+ pid = mingw_spawnve_fd(iprog, argv, env, 1,
+ fhin, fhout, fherr);
free(iprog);
}
argv[0] = argv0;
}
else
- pid = mingw_spawnve(prog, argv, env, 0);
+ pid = mingw_spawnve_fd(prog, argv, env, 0,
+ fhin, fhout, fherr);
free(prog);
}
free_path_split(path);
diff --git a/compat/mingw.h b/compat/mingw.h
index e681135..238fd70 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -220,7 +220,8 @@ int mingw_fstat(int fd, struct stat *buf);
int mingw_utime(const char *file_name, const struct utimbuf *times);
#define utime mingw_utime
-pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env);
+pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env,
+ int fhin, int fhout, int fherr);
void mingw_execvp(const char *cmd, char *const *argv);
#define execvp mingw_execvp
diff --git a/run-command.c b/run-command.c
index cf2d8f7..d270664 100644
--- a/run-command.c
+++ b/run-command.c
@@ -8,12 +8,14 @@ static inline void close_pair(int fd[2])
close(fd[1]);
}
+#ifndef WIN32
static inline void dup_devnull(int to)
{
int fd = open("/dev/null", O_RDWR);
dup2(fd, to);
close(fd);
}
+#endif
int start_command(struct child_process *cmd)
{
@@ -135,42 +137,30 @@ fail_pipe:
strerror(failed_errno = errno));
#else
{
- int s0 = -1, s1 = -1, s2 = -1; /* backups of stdin, stdout, stderr */
+ int fhin = 0, fhout = 1, fherr = 2;
const char **sargv = cmd->argv;
char **env = environ;
- if (cmd->no_stdin) {
- s0 = dup(0);
- dup_devnull(0);
- } else if (need_in) {
- s0 = dup(0);
- dup2(fdin[0], 0);
- } else if (cmd->in) {
- s0 = dup(0);
- dup2(cmd->in, 0);
- }
-
- if (cmd->no_stderr) {
- s2 = dup(2);
- dup_devnull(2);
- } else if (need_err) {
- s2 = dup(2);
- dup2(fderr[1], 2);
- }
-
- if (cmd->no_stdout) {
- s1 = dup(1);
- dup_devnull(1);
- } else if (cmd->stdout_to_stderr) {
- s1 = dup(1);
- dup2(2, 1);
- } else if (need_out) {
- s1 = dup(1);
- dup2(fdout[1], 1);
- } else if (cmd->out > 1) {
- s1 = dup(1);
- dup2(cmd->out, 1);
- }
+ if (cmd->no_stdin)
+ fhin = open("/dev/null", O_RDWR);
+ else if (need_in)
+ fhin = dup(fdin[0]);
+ else if (cmd->in)
+ fhin = dup(cmd->in);
+
+ if (cmd->no_stderr)
+ fherr = open("/dev/null", O_RDWR);
+ else if (need_err)
+ fherr = dup(fderr[1]);
+
+ if (cmd->no_stdout)
+ fhout = open("/dev/null", O_RDWR);
+ else if (cmd->stdout_to_stderr)
+ fhout = dup(fherr);
+ else if (need_out)
+ fhout = dup(fdout[1]);
+ else if (cmd->out > 1)
+ fhout = dup(cmd->out);
if (cmd->dir)
die("chdir in start_command() not implemented");
@@ -181,7 +171,8 @@ fail_pipe:
cmd->argv = prepare_git_cmd(cmd->argv);
}
- cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, env);
+ cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, env,
+ fhin, fhout, fherr);
failed_errno = errno;
if (cmd->pid < 0 && (!cmd->silent_exec_failure || errno != ENOENT))
error("cannot spawn %s: %s", cmd->argv[0], strerror(errno));
@@ -192,12 +183,12 @@ fail_pipe:
free(cmd->argv);
cmd->argv = sargv;
- if (s0 >= 0)
- dup2(s0, 0), close(s0);
- if (s1 >= 0)
- dup2(s1, 1), close(s1);
- if (s2 >= 0)
- dup2(s2, 2), close(s2);
+ if (fhin != 0)
+ close(fhin);
+ if (fhout != 1)
+ close(fhout);
+ if (fherr != 2)
+ close(fherr);
}
#endif
--
1.6.6.115.gd1ab3
^ permalink raw reply related
* Re: [PATCH] mingw: enable NO_PYTHON
From: Erik Faye-Lund @ 2010-01-07 22:00 UTC (permalink / raw)
To: msysgit; +Cc: git, Erik Faye-Lund
In-Reply-To: <1262901159-1436-1-git-send-email-kusmabite@gmail.com>
Uhm, I just realized that I sent out a patch that wasn't clean against
Junio's master after all. I'll send out a fixed one ASAP.
Sorry about the noise.
On Thu, Jan 7, 2010 at 10:52 PM, Erik Faye-Lund
<kusmabite@googlemail.com> wrote:
> Python is not commonly installed on Windows machines, so
> we should disable it there by default.
>
> Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
> ---
>
> This patch is against Junio's current master, and enables
> msysgit to compile upstream git again after Sverre's addition
> of the python remote-helpers (2fe40b6).
>
> Makefile | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index 1c7668a..a2780a2 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1028,6 +1028,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
> BLK_SHA1 = YesPlease
> NO_INET_PTON = YesPlease
> NO_INET_NTOP = YesPlease
> + NO_PYTHON = YesPlease
> COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch
> COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
> COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o
> --
> 1.6.6.95.g82b1b.dirty
>
>
--
Erik "kusma" Faye-Lund
^ permalink raw reply
* [PATCH] mingw: disable Python
From: Erik Faye-Lund @ 2010-01-07 22:07 UTC (permalink / raw)
To: msysgit; +Cc: git, Erik Faye-Lund
In-Reply-To: <40aa078e1001071400j21900ed1n415394491d469b8c@mail.gmail.com>
Python is not commonly installed on Windows machines, so
we should disable it there by default.
Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
---
This patch is against Junio's current master, and enables
msysgit to compile upstream git again after Sverre's addition
of the python remote-helpers (2fe40b6).
Makefile | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
index 015bfab..0004c52 100644
--- a/Makefile
+++ b/Makefile
@@ -1027,6 +1027,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
OBJECT_CREATION_USES_RENAMES = UnfortunatelyNeedsTo
NO_REGEX = YesPlease
BLK_SHA1 = YesPlease
+ NO_PYTHON = YesPlease
COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o
--
1.6.6.90.g50bc9.dirty
^ permalink raw reply related
* [PATCH] Documentation: pack-objects: Clarify --local's semantics.
From: Nelson Elhage @ 2010-01-07 22:10 UTC (permalink / raw)
To: git, gitster; +Cc: Nelson Elhage
The current documentation suggests that --local also ignores any
objects in local packs, which is incorrect. Change the language to be
clearer and more parallel to the other options that ignore objects.
While we're at it, fix a trivial error in --incremental's
documentation.
Signed-off-by: Nelson Elhage <nelhage@mit.edu>
---
Documentation/git-pack-objects.txt | 9 ++++-----
1 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/Documentation/git-pack-objects.txt b/Documentation/git-pack-objects.txt
index f54d433..d8e5686 100644
--- a/Documentation/git-pack-objects.txt
+++ b/Documentation/git-pack-objects.txt
@@ -117,14 +117,13 @@ base-name::
standard input.
--incremental::
- This flag causes an object already in a pack ignored
+ This flag causes an object already in a pack to be ignored
even if it appears in the standard input.
--local::
- This flag is similar to `--incremental`; instead of
- ignoring all packed objects, it only ignores objects
- that are packed and/or not in the local object store
- (i.e. borrowed from an alternate).
+ This flag causes an object that is borrowed from an alternate
+ object store to be ignored even if it appears in the standard
+ input.
--non-empty::
Only create a packed archive if it would contain at
--
1.6.5.40.g402af7
^ permalink raw reply related
* Re: Difference between pull --rebase and fetch+rebase
From: Santi Béjar @ 2010-01-07 22:33 UTC (permalink / raw)
To: martinvz; +Cc: git
In-Reply-To: <1262889864880-4268064.post@n2.nabble.com>
[Do not top post, as it breaks the conversation flow]
On Thu, Jan 7, 2010 at 7:44 PM, martinvz
<martin.von.zweigbergk@gmail.com> wrote:
>
> Thanks for your post, Santi. I can not share my repository since it is a
> project at work. I was troubleshooting a bit myself and found the following
> section in git-pull.sh:
>
> oldremoteref="$(git rev-parse -q --verify "$remoteref")" &&
> for reflog in $(git rev-list -g $remoteref 2>/dev/null)
> do
> if test "$reflog" = "$(git merge-base $reflog $curr_branch)"
> then
> oldremoteref="$reflog"
> break
> fi
> done
>
> Why is it that reflog entries are allowed to override the remote reference?
This is used when the upstream branch is rebased, as you only want to
rebase the local commits and not commits in the old upstream branch.
Is your upstream branch rebased?
Can you provide, at least, a graph of your history (ala git log
--graph --oneline for example)? And plot also the reflog entries and
all the important commits.
Santi
^ permalink raw reply
* Problem Using Git with Subversion Repository
From: Bryan Richardson @ 2010-01-07 22:53 UTC (permalink / raw)
To: git
Hello all,
Has anyone come across a similar problem as this?
Item already exists in filesystem: File already exists: filesystem
'/usr/local/svn/repos/my-apps/db', transaction '96-2v', path
'/app/trunk/vendor/rails/actionpack/test/fixtures/layout_tests/layouts/symlinked'
at /usr/lib/git-core/git-svn line 508
I *think* what happened is in a previous git-svn dcommit I removed the
vendor/rails directory (unfroze rails from my app) and now I'm trying
to freeze it again, in which case git-svn thinks a file needs to be
added (instead of modified) and the Subversion repository says the
file already exists.
Anyone know a way around it?!
--
Thanks!
Bryan
^ 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