{"thread":{"id":"18766","subject":"git rebase -i (and gitk) problem in Windows/Cygwin","startedAt":"2009-04-07T14:18:20Z","lastAt":"2009-04-20T12:47:53Z","messageCount":5,"participants":["Hannu Koivisto","Johannes Schindelin","Alex Riesen"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"110707","messageId":"831vs4im37.fsf@kalahari.s2.org","threadId":"18766","inReplyTo":null,"subject":"git rebase -i (and gitk) problem in Windows/Cygwin","fromName":"Hannu Koivisto","fromEmail":"azure@iki.fi","sentAt":"2009-04-07T14:18:20Z","receivedAt":"2009-04-07T14:18:20Z","isPatch":false,"sender":{"key":"azure@iki.fi","avatar":null},"body":"Greetings,\n\nWith current git.git (1.6.2.2.446.gfbdc0) built for Cygwin, running\non Windows XP, executing the following commands...\n\nmkdir test\ncd test\ngit init\n\necho initial > kala.c\necho initial > sur.c\ngit add *.c\ngit commit -m \"Initial commit.\"\n\necho addition >> kala.c\ngit commit -a -m \"Kala addition 1.\"\n\necho addition >> sur.c\ngit commit -a -m \"Sur addition.\"\n\necho addition2 >> kala.c\ngit commit -a -m \"Kala addition 2.\"\n\ngit rebase -i HEAD~3\n\n...and moving commit \"Kala addition 2.\" right after \"Kala addition\n1.\" and marking it to be squashed results to\n\n---8<----------------------------------------------------\nerror: Entry 'kala.c' not uptodate. Cannot merge.\nfatal: merging of trees 787519579d90e45dfee00189985fa8c92f56be8f and 83f124d88764604c7d348e73103168bd98665e56 failed\n\nCould not apply 14eb9c7... Kala addition 2.\n---8<----------------------------------------------------\n\nrebase -i used to work fine earlier, but unfortunately I don't\nremember which version I used back then (1.6.something).\n\nThis problem doesn't occur on Linux with the same git version.\n\nI don't know if it might be related (I suppose it could be because\nof that \"...not uptodate\" message) but I also see the following\nbehaviour with gitk:\n\n* I change a file in workspace.\n* I \"Update\" in gitk - I see the change.\n* I undo the change.\n* I \"Update\" in gitk - I see an empty change.\n* \"Reload\" doesn't help - I still se an empty change.\n* I run \"git status\" on the command line and then select \"Update\"\n  in gitk -> now the change disappears.\n\n-- \nHannu\n"},{"id":"110709","messageId":"alpine.DEB.1.00.0904071624250.6897@intel-tinevez-2-302","threadId":"18766","inReplyTo":"831vs4im37.fsf@kalahari.s2.org","subject":"Re: git rebase -i (and gitk) problem in Windows/Cygwin","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-04-07T14:25:16Z","receivedAt":"2009-04-07T14:25:16Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Tue, 7 Apr 2009, Hannu Koivisto wrote:\n\n> * I change a file in workspace.\n> * I \"Update\" in gitk - I see the change.\n> * I undo the change.\n> * I \"Update\" in gitk - I see an empty change.\n> * \"Reload\" doesn't help - I still se an empty change.\n> * I run \"git status\" on the command line and then select \"Update\"\n>   in gitk -> now the change disappears.\n\nWhat does \"git diff\" say?  It may be an autocrlf issue or a file mode \nissue.\n\nCiao,\nDscho\n"},{"id":"110712","messageId":"83ws9wh5w9.fsf@kalahari.s2.org","threadId":"18766","inReplyTo":"alpine.DEB.1.00.0904071624250.6897@intel-tinevez-2-302","subject":"Re: git rebase -i (and gitk) problem in Windows/Cygwin","fromName":"Hannu Koivisto","fromEmail":"azure@iki.fi","sentAt":"2009-04-07T14:53:26Z","receivedAt":"2009-04-07T14:53:26Z","isPatch":false,"sender":{"key":"azure@iki.fi","avatar":null},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> Hi,\n>\n> On Tue, 7 Apr 2009, Hannu Koivisto wrote:\n>\n>> * I change a file in workspace.\n>> * I \"Update\" in gitk - I see the change.\n>> * I undo the change.\n>> * I \"Update\" in gitk - I see an empty change.\n>> * \"Reload\" doesn't help - I still se an empty change.\n>> * I run \"git status\" on the command line and then select \"Update\"\n>>   in gitk -> now the change disappears.\n>\n> What does \"git diff\" say?  It may be an autocrlf issue or a file mode \n> issue.\n\nIt outputs only one line \"diff --git a/path/to/file\" (where the\nfile is the one I modified and then undid the modification).  After\nI run \"git status\", it outputs absolutely nothing.\n\nIn my gitk problem case I have autocrlf and safecrlf toggled on for\nthe repository and crlf attribute forced for the file in question.\nIt was in this repository I also first saw the rebase problem but\nwhen I ran the shown test case, autocrlf and safecrlf were off\n(they are globally off and I just toggle them on for some\nrepositories).\n\nI remember seeing and reporting a similar \"spurious changes in\ngitk\" problem a long time ago and I recall back then Junio came up\nwith some file mode related modification.  I haven't seen the\nproblem since until now.\n\n-- \nHannu\n"},{"id":"111723","messageId":"83ljpvh6mk.fsf@kalahari.s2.org","threadId":"18766","inReplyTo":"831vs4im37.fsf@kalahari.s2.org","subject":"Re: git rebase -i (and gitk) problem in Windows/Cygwin","fromName":"Hannu Koivisto","fromEmail":"azure@iki.fi","sentAt":"2009-04-20T12:06:11Z","receivedAt":"2009-04-20T12:06:11Z","isPatch":false,"sender":{"key":"azure@iki.fi","avatar":null},"body":"Hannu Koivisto <azure@iki.fi> writes:\n\n> Greetings,\n>\n> With current git.git (1.6.2.2.446.gfbdc0) built for Cygwin, running\n> on Windows XP, executing the following commands...\n>\n> mkdir test\n> cd test\n> git init\n>\n> echo initial > kala.c\n> echo initial > sur.c\n> git add *.c\n> git commit -m \"Initial commit.\"\n>\n> echo addition >> kala.c\n> git commit -a -m \"Kala addition 1.\"\n>\n> echo addition >> sur.c\n> git commit -a -m \"Sur addition.\"\n>\n> echo addition2 >> kala.c\n> git commit -a -m \"Kala addition 2.\"\n>\n> git rebase -i HEAD~3\n>\n> ...and moving commit \"Kala addition 2.\" right after \"Kala addition\n> 1.\" and marking it to be squashed results to\n>\n> ---8<----------------------------------------------------\n> error: Entry 'kala.c' not uptodate. Cannot merge.\n> fatal: merging of trees 787519579d90e45dfee00189985fa8c92f56be8f and 83f124d88764604c7d348e73103168bd98665e56 failed\n>\n> Could not apply 14eb9c7... Kala addition 2.\n> ---8<----------------------------------------------------\n>\n> rebase -i used to work fine earlier, but unfortunately I don't\n> remember which version I used back then (1.6.something).\n>\n> This problem doesn't occur on Linux with the same git version.\n\nFor what it's worth, I managed to bisect the rebase problem down to\ncommit e4c7292353dbef39feac1c6a60c5cde9140520a6 by Kjetil Barvik:\n\n    write_entry(): use fstat() instead of lstat() when file is open\n\n    Currently inside write_entry() we do an lstat(path, &st) call on a\n    file which have just been opened inside the exact same function.  It\n    should be better to call fstat(fd, &st) on the file while it is open,\n    and it should be at least as fast as the lstat() method.\n\n> I don't know if it might be related (I suppose it could be because\n> of that \"...not uptodate\" message) but I also see the following\n> behaviour with gitk:\n>\n> * I change a file in workspace.\n> * I \"Update\" in gitk - I see the change.\n> * I undo the change.\n> * I \"Update\" in gitk - I see an empty change.\n> * \"Reload\" doesn't help - I still se an empty change.\n> * I run \"git status\" on the command line and then select \"Update\"\n>   in gitk -> now the change disappears.\n\n-- \nHannu\n"},{"id":"111726","messageId":"81b0412b0904200547g3151ce70l9327bb287da4fdd0@mail.gmail.com","threadId":"18766","inReplyTo":"831vs4im37.fsf@kalahari.s2.org","subject":"Re: git rebase -i (and gitk) problem in Windows/Cygwin","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2009-04-20T12:47:53Z","receivedAt":"2009-04-20T12:47:53Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"2009/4/7 Hannu Koivisto <azure@iki.fi>:\n> ---8<----------------------------------------------------\n> error: Entry 'kala.c' not uptodate. Cannot merge.\n> fatal: merging of trees 787519579d90e45dfee00189985fa8c92f56be8f and 83f124d88764604c7d348e73103168bd98665e56 failed\n>\n> Could not apply 14eb9c7... Kala addition 2.\n> ---8<----------------------------------------------------\n>\n> rebase -i used to work fine earlier, but unfortunately I don't\n> remember which version I used back then (1.6.something).\n\nFWIW, I cannot reproduce it. I have quite a bit of changes in my tree\nthough, and maybe that cygwin fstat patches can help...\n(I believe I posted them, but attached anyway.\nI didn't try to revert them and retest, sorry)\n\n\nFrom 7380e8022fffd1f9baa0f45174c6406a700d61f9 Mon Sep 17 00:00:00 2001\nFrom: Alex Riesen <raa.lkml@gmail.com>\nDate: Thu, 19 Mar 2009 15:18:00 +0100\nSubject: [PATCH] Add a fast version of fstat to cygwin port\n\nBesides, the output of the fast stat and lstat is not compatible\nwith cygwin's fstat with regard to uid, gid and ctime fields.\n\nSigned-off-by: Alex Riesen <raa.lkml@gmail.com>\n---\n compat/cygwin.c |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++---\n compat/cygwin.h |    2 +\n 2 files changed, 58 insertions(+), 4 deletions(-)\n\ndiff --git a/compat/cygwin.c b/compat/cygwin.c\nindex ebac148..e91af4f 100644\n--- a/compat/cygwin.c\n+++ b/compat/cygwin.c\n@@ -15,6 +15,18 @@ static inline void filetime_to_timespec(const FILETIME *ft, struct timespec *ts)\n \n #define size_to_blocks(s) (((s)+511)/512)\n \n+/*\n+ * Initialize the fields of struct stat which this implementation\n+ * considers constant on this platform. See also mingw.c\n+ */\n+static void dosify_statbuf(struct stat *buf)\n+{\n+\tbuf->st_dev = buf->st_rdev = 0; /* not used by Git */\n+\tbuf->st_ino = 0;\n+\tbuf->st_nlink = 1;\n+\tbuf->st_uid = buf->st_gid = 0;\n+}\n+\n /* do_stat is a common implementation for cygwin_lstat and cygwin_stat.\n  *\n  * To simplify its logic, in the case of cygwin symlinks, this implementation\n@@ -41,11 +53,8 @@ static int do_stat(const char *file_name, struct stat *buf, stat_fn_t cygstat)\n \t\t\treturn cygstat(file_name, buf);\n \n \t\t/* fill out the stat structure */\n-\t\tbuf->st_dev = buf->st_rdev = 0; /* not used by Git */\n-\t\tbuf->st_ino = 0;\n+\t\tdosify_statbuf(buf);\n \t\tbuf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);\n-\t\tbuf->st_nlink = 1;\n-\t\tbuf->st_uid = buf->st_gid = 0;\n #ifdef __CYGWIN_USE_BIG_TYPES__\n \t\tbuf->st_size = ((_off64_t)fdata.nFileSizeHigh << 32) +\n \t\t\tfdata.nFileSizeLow;\n@@ -85,6 +94,41 @@ static int cygwin_stat(const char *path, struct stat *buf)\n \treturn do_stat(path, buf, stat);\n }\n \n+#undef fstat\n+static int cygwin_fstat(int fd, struct stat *buf)\n+{\n+\tHANDLE fh = (HANDLE)_get_osfhandle(fd);\n+\tBY_HANDLE_FILE_INFORMATION fdata;\n+\n+\tif (fh == INVALID_HANDLE_VALUE) {\n+\t\terrno = EBADF;\n+\t\treturn -1;\n+\t}\n+\t/* direct non-file handles to cygwin's fstat() */\n+\tif (GetFileType(fh) != FILE_TYPE_DISK)\n+\t\treturn fstat(fd, buf);\n+\n+\tif (!buf) {\n+\t\terrno = EINVAL;\n+\t\treturn -1;\n+\t}\n+\tif (GetFileInformationByHandle(fh, &fdata)) {\n+\t\tdosify_statbuf(buf);\n+\t\tbuf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);\n+#ifdef __CYGWIN_USE_BIG_TYPES__\n+\t\tbuf->st_size = ((_off64_t)fdata.nFileSizeHigh << 32) +\n+\t\t\tfdata.nFileSizeLow;\n+#else\n+\t\tbuf->st_size = (off_t)fdata.nFileSizeLow;\n+#endif\n+\t\tfiletime_to_timespec(&fdata.ftLastAccessTime, &buf->st_atim);\n+\t\tfiletime_to_timespec(&fdata.ftLastWriteTime, &buf->st_mtim);\n+\t\tfiletime_to_timespec(&fdata.ftCreationTime, &buf->st_ctim);\n+\t\treturn 0;\n+\t}\n+\terrno = EBADF;\n+\treturn -1;\n+}\n \n /*\n  * At start up, we are trying to determine whether Win32 API or cygwin stat\n@@ -119,9 +163,11 @@ static int init_stat(void)\n \t\tif (!core_filemode && native_stat) {\n \t\t\tcygwin_stat_fn = cygwin_stat;\n \t\t\tcygwin_lstat_fn = cygwin_lstat;\n+\t\t\tcygwin_fstat_fn = cygwin_fstat;\n \t\t} else {\n \t\t\tcygwin_stat_fn = stat;\n \t\t\tcygwin_lstat_fn = lstat;\n+\t\t\tcygwin_fstat_fn = fstat;\n \t\t}\n \t\treturn 0;\n \t}\n@@ -138,6 +184,12 @@ static int cygwin_lstat_stub(const char *file_name, struct stat *buf)\n \treturn (init_stat() ? lstat : *cygwin_lstat_fn)(file_name, buf);\n }\n \n+static int cygwin_fstat_stub(int fd, struct stat *buf)\n+{\n+\treturn (init_stat() ? fstat : *cygwin_fstat_fn)(fd, buf);\n+}\n+\n stat_fn_t cygwin_stat_fn = cygwin_stat_stub;\n stat_fn_t cygwin_lstat_fn = cygwin_lstat_stub;\n+int (*cygwin_fstat_fn)(int fd, struct stat *) = cygwin_fstat_stub;\n \ndiff --git a/compat/cygwin.h b/compat/cygwin.h\nindex a3229f5..fd54c82 100644\n--- a/compat/cygwin.h\n+++ b/compat/cygwin.h\n@@ -4,6 +4,8 @@\n typedef int (*stat_fn_t)(const char*, struct stat*);\n extern stat_fn_t cygwin_stat_fn;\n extern stat_fn_t cygwin_lstat_fn;\n+extern int (*cygwin_fstat_fn)(int fd, struct stat *);\n \n #define stat(path, buf) (*cygwin_stat_fn)(path, buf)\n #define lstat(path, buf) (*cygwin_lstat_fn)(path, buf)\n+#define fstat(fd, buf) (*cygwin_fstat_fn)(fd, buf)\n-- \n1.6.3.rc0.45.g63634\n\n"}]}