8000 git compress adds main branch files to feature branch · Issue #4845 · git-town/git-town · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

git compress adds main branch files to feature branch #4845

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
AmitJoki opened this issue May 2, 2025 · 11 comments · Fixed by #4881
Closed
8000

git compress adds main branch files to feature branch #4845

AmitJoki opened this issue May 2, 2025 · 11 comments · Fixed by #4881

Comments

@AmitJoki
Copy link
AmitJoki commented May 2, 2025

main is several commits ahead of feature

In feature, we do git compress without first doing git sync, my expectation would be that git compress would first rebase feature from main and then squash the commits. i.e. git compress = git sync && git compress

In feature there's 7 files changed. After git compress run without prior git sync, it adds all the files from main in this branch and I end up getting 125 files changes not related to my PR.

@AmitJoki
Copy link
Author
AmitJoki commented May 2, 2025

@kevgo sorry missed this in the document:

Branches must be in sync to compress them; run git town sync before running this command.

Any reason git sync is not run prior to git compress automatically? If there are merge conflicts, I'd guess the steps of remediation would still apply in the same way?

If for some reason git sync can't be auto-run whenever git compress is run, perhaps it could fail if it knows the branch is out of sync or warn the user that the changes might end up in the PR.

@kevgo
Copy link
Contributor
kevgo commented May 2, 2025

Thanks for reaching out about this. You raise a good point.

Why no built-in syncing

In the past, most Git Town commands were also syncing branches. The idea was to minimize the commands the user needs to type into the terminal. We got user feedback that this isn't always desirable:

  • Many people want to control when they sync branches. An example is users in a busy monorepo, where each sync causes expensive recompilation. These users are surprised if Git Town commands sync unexpectedly.
  • Both syncing and the actual activity of the command (in this case compressing) might cause merge conflicts. When resolving those merge conflicts, people might get confused which exact merge conflict they are currently resolving.

So we decided to untangle syncing from Git Town commands where it makes sense.

Pulling in changes from the main branch

This seems like a bug. This test script reproduces the behavior:

git init test
cd test
git commit --allow-empty -m "Initial"

echo "CREATING BRANCH"
git town hack feature
echo "change on feature" > feature_file
git add .
git commit -m "Feature commit"

echo "ADDING COMMIT TO THE MAIN BRANCH"
git checkout main
echo "change on main" > 
8000
main_file
git add .
git commit -m "Main commit"

echo "COMPRESSING"
git checkout feature
git town compress

echo "NEW COMMIT ON FEATURE"
git show

Output:

NEW COMMIT ON BRANCH
commit 7f8b1319c28dcc9ea4408969df3df67792f22c9f (HEAD -> branch)
Author: Kevin Goslar <kevin.goslar@gmail.com>
Date:   Fri May 2 16:42:35 2025 -0500

    Branch commit

diff --git a/branch_file b/branch_file
new file mode 100644
index 0000000..4d3c629
--- /dev/null
+++ b/feature_file
@@ -0,0 +1 @@
+change on feature
diff --git a/main_file b/main_file
deleted file mode 100644
index 805770e..0000000
--- a/main_file
+++ /dev/null
@@ -1 +0,0 @@
-change on main

The compressed commit on the feature branch is now undoing the change made by the commit on the main branch. This is a bug. There are two ways forward :

  1. Tell the user to sync and then compress again. Yes, that sounds lazy (Git Town knows that it should sync, why doesn't it do it right there), but this avoids confusion about the nature of possible merge conflicts.

  2. Change the compress logic so that the compressed commit is exactly where the old commit was, at the merge-base of branches "feature" and "main". A challenge with that is possibly lost data in crazy edge cases. People use Git Town in a wide variety of ways and setups. The prime directive for Git Town is to never lose user data.

@kevgo kevgo reopened this May 2, 2025
@kevgo
Copy link
Contributor
kevgo commented May 2, 2025

Possible implementation of (2):

git init test
cd test
git commit --allow-empty -m "Initial commit"

echo CREATING BRANCH
git town hack feature
echo "change on feature" > feature_file
git add .
git commit -m "Feature commit"

echo ADDING COMMIT TO THE MAIN BRANCH
git checkout main
echo "change on main" > main_file
git add .
git commit -m "Main commit"

echo DETERMINING MERGE BASE
mergebase=$(git merge-base main feature)
echo $mergebase
# prints the SHA of "Initial commit"

echo COMPRESSING
git checkout feature
git reset --soft $mergebase
git commit -m "Feature commit"

echo "NEW COMMIT ON FEATURE"
git show

As long as git merge-base works, this seems to work. Output:

NEW COMMIT ON FEATURE
commit 8627ddc841d722fbd5e26a5717dd0d37b2b1243a (HEAD -> branch)
Author: Kevin Goslar <kevin.goslar@gmail.com>
Date:   Fri May 2 17:04:26 2025 -0500

    Branch commit

diff --git a/feature_file b/feature_file
new file mode 100644
index 0000000..4d3c629
--- /dev/null
+++ b/feature_file
@@ -0,0 +1 @@
+change on feature

The compressed commit no longer contains or undoes the commit on main.

@kevgo
Copy link
Contributor
kevgo commented May 2, 2025

git merge-base seems to work even if the first commit on the feature branch is a merge commit:

git init test
cd test
git commit --allow-empty -m "Initial commit"

echo CREATING EMPTY FEATURE BRANCH
git town hack feature

echo ADD COMMIT 1 TO THE MAIN BRANCH
git checkout main
echo "change on main 1" > main_file
git add .
git commit -m "Main commit 1"

ECHO MERGING MAIN INTO FEATURE
git checkout feature
git merge main --no-edit --no-ff

ECHO ADD COMMIT TO FEATURE
echo "change on feature" > feature_file
git add .
git commit -m "Feature commit"

echo ADD COMMIT 2 TO THE MAIN BRANCH
git checkout main
echo "change on main 2" > main_file
git add .
git commit -m "Main commit 2"

echo DETERMINING MERGE BASE
mergebase=$(git merge-base main feature)
echo $mergebase

echo COMPRESSING
git checkout feature
git reset --soft $mergebase
git commit -m "Feature commit"

echo COMPRESSED COMMIT ON FEATURE
git show

Output:

COMPRESSED COMMIT ON FEATURE
commit 0825010ff15a5251ccc58d9fab9e6d6daa57b098 (HEAD -> feature)
Author: Kevin Goslar <kevin.goslar@gmail.com>
Date:   Fri May 2 17:18:13 2025 -0500

    Feature commit

diff --git a/feature_file b/feature_file
new file mode 100644
index 0000000..1a58e8f
--- /dev/null
+++ b/feature_file
@@ -0,0 +1 @@
+change on feature

The commits are okay too:

~/test > git log
commit 0825010ff15a5251ccc58d9fab9e6d6daa57b098 (HEAD -> feature)
Author: Kevin Goslar <kevin.goslar@gmail.com>
Date:   Fri May 2 17:18:13 2025 -0500

    Feature commit

commit 4883cae7ea02efbf07a09db6fa7ad7713907466f
Author: Kevin Goslar <kevin.goslar@gmail.com>
Date:   Fri May 2 17:18:13 2025 -0500

    Main commit 1

commit 81a93d2271ae03f32e14c5b817164ad54de99f3b
Author: Kevin Goslar <kevin.goslar@gmail.com>
Date:   Fri May 2 17:18:12 2025 -0500

    Initial commit

@AmitJoki
Copy link
Author
AmitJoki commented May 5, 2025

Thanks for noticing the bugs and working on a fix quickly. I'd thought as much w.r.t why git sync might not have been automatically called.

My suggestion was going to be that for a git compress, following steps will be taken:

  1. Do a dry run of git sync first.
  2. Check if merge conflicts is present.
  3. If yes, abort the command wholly saying "Run git sync first and resolve the merge conflicts"
  4. If no, then we can now just do compress.

Here if there's no merge conflicts, everything works transparently and if not, throws an explicit error stating the exact next steps to take.

But I see that you've come up with another solution that might solve this issue even more transparently. Thanks!

@kevgo
Copy link
Contributor
kevgo commented May 7, 2025

One challenge with your proposed workflow arises in this scenario:

  • The main branch has commits that the branch being compressed doesn’t have.
  • These differences don’t cause merge conflicts.

In that case, the dry-run sync sees no conflicts, assumes the branches are in sync, and proceeds to compress, effectively reversing those non-conflicting changes from the main branch.

On the flip side, a downside of the approach I suggested is that if the merge base with the parent branch is incorrect or stale, the compression might only include part of the intended changes or too much.

Given that, your other idea might be the safest path forward: detect whether the branch is fully in sync with its parent, and only allow compression if it is. The most reliable way I can think of to verify sync is to check whether the merge-base is equal to the parent branch’s HEAD SHA.

If needed, we could introduce a --force flag to bypass this check and compress even when the branches aren't perfectly in sync.

@kevgo
Copy link
Contributor
kevgo commented May 8, 2025

Turns out Git Town already uses a better way to determine whether a branch is in sync with its parent:

git log --no-merges --format=%H parent ^branch

@AmitJoki
Copy link
Author
AmitJoki commented May 8, 2025

@kevgo thanks for the quick fix! Is there a timeline for when this and the compress --no-verifiy changes will be released?

@kevgo
Copy link
Contributor
kevgo commented May 8, 2025

Since this is an important bug fix, and it seems urgent for you to get it, I'll release it today.

@kevgo
Copy link
Contributor
kevgo commented May 8, 2025

This is now available as part of Git Town 20.1.

@AmitJoki
8000 Copy link
Author
AmitJoki commented May 9, 2025

@kevgo thank you for the quick turnaround and release! Love using it!

tmeijn pushed a commit to tmeijn/dotfiles that referenced this issue May 10, 2025
⚠️ **CAUTION: this is a major update, indicating a breaking change!** ⚠️

This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [git-town/git-town](https://github.com/git-town/git-town) | major | `v18.3.2` -> `v20.1.0` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>git-town/git-town (git-town/git-town)</summary>

### [`v20.1.0`](https://github.com/git-town/git-town/releases/tag/v20.1.0)

[Compare Source](git-town/git-town@v20.0.0...v20.1.0)

##### New Features

-   `git town compress` now has a `--no-verify` flag that disables Git's pre-commit hook ([#&#8203;4843](git-town/git-town#4843)).

##### Bug Fixes

-   `git town compress` now enforces that the branch to compress is in sync with its parent branch ([#&#8203;4845](git-town/git-town#4845)).
-   `git town sync` now doesn't remove commits of branches with deleted tracking branch if they don't have descendents ([#&#8203;4872](git-town/git-town#4872)).
-   Git Town no longer overrides the language of executed Git commands to US-English ([#&#8203;4861](git-town/git-town#4861)).

##### Contributors

Shoutout to [@&#8203;AmitJoki](https://github.com/AmitJoki), [@&#8203;fcurella](https://github.com/fcurella), [@&#8203;haltcase](https://github.com/haltcase), [@&#8203;kevgo](https://github.com/kevgo), [@&#8203;lvlcn-t](https://github.com/lvlcn-t), [@&#8203;mw00120](https://github.com/mw00120), [@&#8203;niklastreml](https://github.com/niklastreml), [@&#8203;stephenwade](https://github.com/stephenwade) for contributing code, feedback, and ideas to 34 shipped MRs and 6 resolved issues!

### [`v20.0.0`](https://github.com/git-town/git-town/releases/tag/v20.0.0)

[Compare Source](git-town/git-town@v19.0.0...v20.0.0)

Git Town 2000! 🎉

##### BREAKING CHANGES

-   The `push-new-branches` configuration option is now called `share-new-branches` and allows additional ways of sharing freshly created branches ([#&#8203;3912](git-town/git-town#3912)):
    -   `no`: keep new branches local (default)
    -   `push`: push new branches to the [development remote](https://www.git-town.com/preferences/dev-remote.html)
    -   `propose`: automatically create proposals for new branches. This helps being maximally transparent with progress on each item worked on.
-   `git town propose` now always syncs the proposed branch, but always in [detached mode](https://www.git-town.com/commands/sync.html#-d--detached) mode ([#&#8203;4772](git-town/git-town#4772), [#&#8203;4781](git-town/git-town#4781)).
-   `git town propose` now longer has the `--detached` flag because it now always syncs in detached mode ([#&#8203;4775](git-town/git-town#4775)).

##### New Features

-   `git town sync` now correcly syncs branches whose commits got amended or rebased ([#&#8203;4586](git-town/git-town#4586)).
-   You can now propose all branches in a stack with `git town propose --stack` ([#&#8203;3840](git-town/git-town#3840)).
-   `git town propose` now un-parks parked branches when proposing them ([#&#8203;4780](git-town/git-town#4780)).
-   The [setup assistant](https://www.git-town.com/configuration.html) no longer asks for data already provided by the [Git Town configuration file](https://www.git-town.com/configuration-file.html) ([#&#8203;4710](git-town/git-town#4710)).
-   The setup assistant now offers to store forge API tokens globally for all repos on your machine ([#&#8203;4112](git-town/git-town#4112)).
-   [git town status reset](https://www.git-town.com/commands/status-reset.html) now indicates whether the runstate file existed ([#&#8203;4814](git-town/git-town#4814)).
-   [git town status reset](https://www.git-town.com/commands/status-reset.html) now supports the `--verbose` flag ([#&#8203;4813](git-town/git-town#4813)).

##### Bug Fixes

-   Git Town now correctly resolves `includeIf` directives in Git configuration ([#&#8203;4107](git-town/git-town#4107)).
-   `git town prepend --beam` now works correctly with prototype branches ([#&#8203;4768](git-town/git-town#4768)).
-   Git Town now loads the forge API token with the same precendence as other configuration data ([#&#8203;7428](git-town/git-town#472
73CA
8)).
-   [git town undo](https://www.git-town.com/commands/undo.html) now correctly undoes situations where only the local part of a branch got renamed ([#&#8203;4794](git-town/git-town#4794)).
-   Git Town now works even if Git's `color.ui` setting is `always` ([#&#8203;4840](git-town/git-town#4840)).
-   The setup assistant now only updates the stored access token of the forge that is actually being used ([#&#8203;4819](git-town/git-town#4819)).
-   [git town status reset](https://www.git-town.com/commands/status-reset.html) can now be run from a subdirectory ([#&#8203;4812](git-town/git-town#4812)).

##### Contributors

Git Town 2000 is a big release. Shoutout to [@&#8203;AmitJoki](https://github.com/AmitJoki), [@&#8203;Ydot19](https://github.com/Ydot19), [@&#8203;ahgraber](https://github.com/ahgraber), [@&#8203;davidolrik](https://github.com/davidolrik), [@&#8203;erik-rw](https://github.com/erik-rw), [@&#8203;haltcase](https://github.com/haltcase), [@&#8203;jmyers-figma](https://github.com/jmyers-figma), [@&#8203;judec-ps](https://github.com/judec-ps), [@&#8203;kevgo](https://github.com/kevgo), [@&#8203;lvlcn-t](https://github.com/lvlcn-t), [@&#8203;nekitk](https://github.com/nekitk), [@&#8203;niklastreml](https://github.com/niklastreml), [@&#8203;pradeepmurugesan](https://github.com/pradeepmurugesan), [@&#8203;ruudk](https://github.com/ruudk), [@&#8203;stephenwade](https://github.com/stephenwade), [@&#8203;terheyden](https://github.com/terheyden), [@&#8203;tharun208](https://github.com/tharun208) for contributing code, feedback, and ideas to 124 shipped MRs and 17 resolved issues!

### [`v19.0.0`](https://github.com/git-town/git-town/releases/tag/v19.0.0)

[Compare Source](git-town/git-town@v18.3.2...v19.0.0)

##### BREAKING CHANGES

-   The commands `new-pull-request` and `rename-branch` are being sunset after being deprecated for a long time. Their modern replacements are `propose` and `rename` ([#&#8203;4714](git-town/git-town#4714)).
-   The configuration entries `contribution-branches`, `observed-branches`, `parked-branches`, and `prototype-branches` are being sunset. Their functionality is taken over by setting the type for individual branches as well as `contribution-regex`, `observed-regex`, `default-branch-type`, and `new-branch-type` ([#&#8203;4499](git-town/git-town#4499)).

##### New Features

-   `git town append` and `git town hack` now also have a `--beam` flag to move selected commits to the new branch. When enabled, they no longer fetch or sync, which allows you to move commits with the fewest possible distractions ([#&#8203;3338](git-town/git-town#3338)).
-   The "select commits to beam" dialog now displays the SHA of commits in addition to the commit message ([#&#8203;4519](git-town/git-town#4519)).
-   `set-parent` now allows providing the new parent as an optional positional CLI argument ([documentation](https://www.git-town.com/commands/set-parent.html#positional-argument), [#&#8203;4705](git-town/git-town#4705)).
-   The Git Town website now has a [how-to](https://www.git-town.com/how-tos.html) section.

##### Bug Fixes

-   `git town sync --no-push` no longer make the commit order appear out of order ([#&#8203;4696](git-town/git-town#4696)).

##### Contributors

Shoutout to [@&#8203;erik-rw](https://github.com/erik-rw), [@&#8203;kevgo](https://github.com/kevgo), [@&#8203;legeana](https://github.com/legeana), [@&#8203;nekitk](https://github.com/nekitk), [@&#8203;pradeepmurugesan](https://github.com/pradeepmurugesan), [@&#8203;ruudk](https://github.com/ruudk), [@&#8203;stephenwade](https://github.com/stephenwade), [@&#8203;terheyden](https://github.com/terheyden) for contributing code, ideas, and feedback to 33 shipped MRs and 10 resolved issues!

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC4xMS4yIiwidXBkYXRlZEluVmVyIjoiNDAuMTEuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiUmVub3ZhdGUgQm90Il19-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

2 participants
0