New issue
Advanced search Search tips

Issue 823993 link

Starred by 1 user

Issue metadata

Status: Available
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Bug



Sign in to add a comment

git worktree confounds git rebase-update

Project Member Reported by dgro...@chromium.org, Mar 21 2018

Issue description

After years of using a merge workflow, I tried the chromium-specific workflow that involves `git rebase-update`.

I have two working directories:
~/c/blink/src that I created by `fetch --nohooks chromium` ("main working tree")
~/c/1/src that I created by `git worktree add ../../1/src` ("linked working tree")

The linked working tree has a branch with 1 commit + 1 file modified but not staged or committed.

I ran git rebase-update from the main working tree, which succeeded.

But `git status` in the linked working tree shows that its files have not been updated to reflect the newly retrieved commits. Instead the index has the "reverse diff" of the new commits. e.g. the new commit included
+    "//net",
in components/download/downloader/in_progress/BUILD.gn.

whereas the index in my linked working tree has
-    "//net",
in the same file.

Help? Is rebase-update just incompatible with multiple working directories? Or is there something I can do to get this at least mostly working?
 
Components: Infra>SDK
+ Infra>SDK (Perhaps no one triages Infra>Git ?)

Comment 2 by aga...@chromium.org, Mar 27 2018

Cc: aga...@chromium.org
Components: -Infra>Git
Owner: dgro...@chromium.org
Status: Assigned (was: Untriaged)
git rebase-update was certainly written before 'git worktree' was widely available and stable, and wasn't written with that in mind. The fact that they don't play nicely together isn't particularly surprising to me.

The thing about rebasing is that git is incapable/unwilling to rebase a change without checking it out in the local working tree. And similarly, when the index gets updated, git never changes the working tree to reflect that directly. So when you ran "git rebase-update" in your main working tree, it checked out the same thing as was in your second worktree, rebased it, committed that to the index, and then moved on and checked out other things. Meanwhile, the worktree kept the same files checked out while the index updated out from under it.

I expect that a "git checkout --force name-of-the-branch-it-theoretically-has-checked-out" would fix it. Try that and let me know?
> "git rebase-update" in your main working tree, it checked out the same thing as was in your second worktree

It doesn't literally do that, does it? When I try manually I get an error:

~/c/blink/src(vim)$ git worktree list
/usr/local/google/home/dgrogan/c/blink/src  7833f97aa11b [vim]
/usr/local/google/home/dgrogan/c/1/src      7b9dd868953a [flexbox]

~/c/blink/src(vim)$ git checkout flexbox
fatal: 'flexbox' is already checked out at '/usr/local/google/home/dgrogan/c/1/src'


"git checkout -f <branch>" works well when there are no uncommitted modifications in the file system before the "git rebase-update", but it destroys any changes, staged or unstaged, not already committed (apparently same as "git reset --hard"). Example below.

Would it be possible to teach "git rebase-update" to detect when the branch is checked out in another directory and either skip it or, even better, cd to the directory to perform the freeze/rebase/thaw there?


~/c/1/src(flexbox)$ git status
On branch flexbox
Your branch is ahead of 'origin/master' by 10 commits.
  (use "git push" to publish your local commits)

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   third_party/WebKit/Source/core/layout/ng/ng_flex_layout_algorithm.cc

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	flex_div.html

no changes added to commit (use "git add" and/or "git commit -a")

~/c/blink/src(vim)$ git rebase-update
Fetching origin
remote: Counting objects: 286726, done
remote: Finding sources: 100% (134/134)
remote: Total 134 (delta 1), reused 101 (delta 1)
Receiving objects: 100% (134/134), 454.72 KiB | 1.75 MiB/s, done.
Resolving deltas: 100% (1/1), completed with 1 local object.
From https://chromium.googlesource.com/chromium/src
   dac2831e9f9d..8906d570277c  master     -> origin/master
Rebasing: flexbox
Rebasing: some_topic_branch
Rebasing: vim
Rebasing: flex_debug

~/c/1/src(flexbox)$ git status
On branch flexbox
Your branch is ahead of 'origin/master' by 10 commits.
  (use "git push" to publish your local commits)

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   ash/app_list/app_list_controller_impl.cc
	modified:   ash/app_list/app_list_controller_impl.h
        [snip many files]
	modified:   ui/app_list/views/app_list_view.cc
	modified:   ui/app_list/views/app_list_view.h

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   third_party/WebKit/Source/core/layout/ng/ng_flex_layout_algorithm.cc

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	flex_div.html

~/c/1/src(flexbox)$ # git checkout -f flexbox would clean up the staged area (good) but also blow away the unstaged layout/ng change (bad)
Cc: dgro...@chromium.org
Owner: aga...@chromium.org

Comment 5 by aga...@chromium.org, Apr 10 2018

Owner: ----
Status: Available (was: Assigned)
Honestly, I'm sorry that this doesn't work, but I don't predict that I'll be able to get to this in any reasonable time period. Unassigning from myself so folks don't have incorrect assumptions about when this will be addressed.

Sign in to add a comment