8000 sync: support for amended branches · Issue #4586 · git-town/git-town · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

sync: support for amended branches #4586

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
pradeepmurugesan opened this issue Mar 17, 2025 · 27 comments · Fixed by #4729
Closed
8000

sync: support for amended branches #4586

pradeepmurugesan opened this issue Mar 17, 2025 · 27 comments · Fixed by #4729

Comments

@pradeepmurugesan
Copy link
Member
pradeepmurugesan commented Mar 17, 2025

I have a branch feature-1, which has one commit.

I create another branch feature-2 on top of feature-1 using append . Now my branch lineage looks like this.

  main
    feature1
*     feature2

I do some change in feature-1, but instead of adding as a new commit, I amend the existing commit using

git add .
git commit --amend --no-edit

When I try to sync my stack it checks out feature-2 and rebase with feature-1. Since I amended the commit in feature-1 , this will result in a merge conflict and I need to resolve.

I usually don't change feature-1 commits while working in feature-2. Is it possible to add a flag to tweak this behaviour ? I mean when I sync the stack, can we remove the already existing parent commits in the child branch and perform a rebase ?

In this case, when I sync the stack

checkout feature 2
remove all the existing feature 1 commits
rebase feature 1

Kindly let me know if you need more info.. I have created a repo to demo this.

just make sure the lineage is still present and the strategy is rebase. Perform the following

git-town switch feature2
git-town sync -s
@kevgo
Copy link
Contributor
kevgo commented Mar 25, 2025

Steps to reproduce the problem:

# initialize repo
git init test
cd test
git commit --allow-empty -m "Initial commit"

# create branch feature1
git town hack feature1
echo "one" > file1
git add .
git commit -m "commit 1a"

# create child branch feature2
git town append feature2
echo "two" > file2
git add .
git commit -m "commit 2"

# amend the commit on branch1
git checkout feature1
echo "another one" > file1
git add .
git commit --amend -m "commit 1b"

# rebase branch feature2
git checkout feature2
git rebase feature1

This does indeed result in a merge conflict for file1 on feature2:

<<<<<<< HEAD
another 
one
>>>>>>> 0a250f0 (commit 1a)

Here is the proposed alternative to rebasing, which avoids the merge conflict:

# create a temporary branch that will become the new "feature2" branch
git checkout -b feature2-new feature1

# move the commits from the old feature2 branch over to the new feature2 branch 
git cherry-pick [SHA of "commit2" on feature2]

# point the feature2 branch to the new commits on the temporary branch
git checkout feature2
git reset --hard feature2-new

# push the new commits to the tracking branch
git push --force-with-lease --force-if-includes

# delete the temporary branch
git branch -d feature2-new

@kevgo
Copy link
Contributor
kevgo commented Mar 25, 2025

It's strange that this is necessary, given that a normal Git rebase is defined as "Reapply commits on top of another base tip", which is exactly what we do manually here.

@pradeepmurugesan
Copy link
Member Author

Git rebase is defined as "Reapply commits on top of another base tip", which is exactly what we do manually here.

amend changes the SHA of the commit on the feature1 right ? Not sure if git rebase can identify the amended commit.

Here is the proposed alternative to rebasing

@kevgo Do you think git-town sync with rebase should adopt this as the default behaviour of rebase or controlled by any flag?

Happy to contribute if you think we can add this work around into git-town..

@stephenwade
Copy link
Member

It's strange that this is necessary, given that a normal Git rebase is defined as "Reapply commits on top of another base tip", which is exactly what we do manually here.

git rebase <upstream> will apply "commits in the current branch but that are not in <upstream> … the same set of commits that would be shown by git log <upstream>..HEAD" (see git-rebase docs). After replacing "commit 1a" with the appended "commit 1b" in feature1, the list of commits in feature2 but that are not in feature1 are "commit 1a" and "commit 2".

We can "cherry-pick" just the commits we want with git rebase by using git rebase --onto <newbase> <upstream>. By passing feature1 as the <newbase> and where feature1 used to be as <upstream>, we apply only the desired commits.

Steps reproducing the solution (diff from #4586 (comment)):

 # initialize repo
 git init test
 cd test
 git commit --allow-empty -m "Initial commit"
 
 # create branch feature1
 git town hack feature1
 echo "one" > file1
 git add .
 git commit -m "commit 1a"
 
 # create child branch feature2
 git town append feature2
 echo "two" > file2
 git add .
 git commit -m "commit 2"
 
 # amend the commit on branch1
+FEATURE1_OLD=$(git rev-parse feature1)
 git checkout feature1
 echo "another one" > file1
 git add .
 git commit --amend -m "commit 1b"
 
 # rebase branch feature2
 git checkout feature2
-git rebase feature1
+git rebase --onto feature1 $FEATURE1_OLD

@pradeepmurugesan
Copy link
Member Author

I tried with few more commits in feature1 and amended the commits using interactive rebase. The solution works.

However I am not able to understand how will this work with git-town as amending the commit happens outside git-town. I mean how can git-town know about the FEATURE1_OLD ?

@stephenwade
Copy link
Member

For each branch, Git Town should track the parent's HEAD as well. That way, Git Town knows which commits are considered part of this branch, even if the parent's HEAD changes. I don't know enough about the internals to know whether this is already happening, but it should be possible.

@pradeepmurugesan
Copy link
Member Author

@kevgo do you think this can be to accommodated into git-town ?

I am happy to contribute if that is the case. Kindly let me know.

@kevgo
Copy link
Contributor
kevgo commented Apr 1, 2025

This addresses the most widely requested open issue: #2223. It does so in a better way than earlier ideas, like #3179. Thanks @stephenwade for figuring out how to implement this idiomatically! 🙏 We finally have a solution good enough to add to Git Town, so let's build this.

Git Town already tracks the last known SHA for each local and remote branch in its runstate file. You can see the content of the runstate file by executing git town status show. Currently, this data is used to undo the most recent Git Town command. It makes perfect sense to also use it to sync better.

All we have to do is modify the rebase sync strategy to run the commands outlined in this ticket if there is a useful runstate file. Otherwise keep doing the existing behavior. Hopefully, our pretty comprehensive end-to-end test suite will reveal edge cases where this doesn't work as expected.

@pradeepmurugesan any help with Git Town would be greatly appreciated. Unfortunately, the sync algorithm is the most complex part of Git Town, so this ticket is the pretty much the polar opposite of a "good first issue". If you haven't already, please take a look at the developer documentation. The architecture document gives some background on the codebase. A good starting point is https://github.com/git-town/git-town/blob/main/internal/cmd/sync/sync_branch.go, which implements the logic to sync a Git branch. Please don't hesitate to reach out with any questions, no matter how big or small!

@kevgo kevgo marked this as a duplicate of #3179 Apr 1, 2025
@kevgo
Copy link
Contributor
8000 kevgo commented Apr 1, 2025

I added an end-to-end test that documents the problematic behavior of the existing codebase: #4631

@pradeepmurugesan
Copy link
Member Author

Thank you for the pointers. I will take a look and get back to you with questions. 👍

@pradeepmurugesan
Copy link
Member Author

@kevgo I have a naive question regarding the tests.. I tried to run the end to end test to understand how the setup works.. I see the test_runner.go runs the command configured in the feature file.

I added a print statement to the sync logic and tried running the test adding additional branches while resolving conflicts in features/sync/current_branch/feature_branch/change_repo_in_between/create_branch.feature.

I don't see the logs I added getting printed, When I tried to debug the debug points were not hit. I tired following the test_runner.go and I see it executes these commands via exec , subProcess.Run() .. I doubt whether this uses the local installation instead of the code.

Am I understanding this correctly ? If so is there anyway i can make these end to end tests execute the changes I made in the code ? Kindly clarify 🙏

@kevgo
Copy link
Contributor
kevgo commented Apr 7, 2025

Great questions—you're definitely on the right track! test_runner.go does indeed invoke the locally installed Git Town binary (the one in ~/go/bin/) via a subshell. By default, the output of that subshell is captured, which is why you don’t see it directly in the terminal.

A few more details to round out the picture:

  • The tests are written in Cucumber, using the Go implementation of Cucumber.

  • Each line in a .feature file represents a Step, which maps to some Go test code. That test logic is run with data parsed from the step.

  • All step implementations live in steps.go. For example, here is the implementation for the And I run "git town sync" step:

    sc.Step(`^I run "(.+)"$`, func(ctx context.Context, command string) {
    runCommand(ctx, command)
    })

    This step calls runCommand(ctx, command), which in turn calls devRepo.MustQueryStringCode(command). The latter is a method on TestRunner.

To run an end-to-end test and view your debug logs, please follow these steps:

  1. Add the tags @this and @debug to the Cucumber scenario you want to debug. In your case, you'd update features/sync/current_branch/feature_branch/change_repo_in_between/create_branch.feature around line 32 like so:

    + @debug
    + @this
    Scenario: result
      Then Git Town runs the commands
        | BRANCH    | COMMAND  |
        | feature-1 | git push |
  2. Run make cukethis. This builds the Git Town binary and executes only the scenario tagged with @this. The @debug tag causes a detailed trace of all activity: How it runs various Git commands to prepare a Git repo for the test, then runs Git Town, and then runs more Git commands to inspect the repo after the test ran. Scroll through the logs to find the Git Town command output, including any log statements you have added.

That's the easiest way to debug. If you prefer to debug interactively in VSCode, please follow the instructions in https://github.com/git-town/git-town/blob/main/docs/DEVELOPMENT.md#debug-end-to-end-tests.

And of course, if you have ideas for how we can make this process smoother or more intuitive, I’d love to hear them!

@erik-rw
Copy link
erik-rw commented Apr 8, 2025

If I have to amend an existing commit as shown in the example, I usually do manual rebase -i s to get rid of the outdated commit from the child branches.

Using the data from the runstate file and solving this automatically sounds perfect. But there is the caveat that running manual rebase in between git town commands will get the runstate file out of sync. And the next git town sync will have unforeseeable side effects.
Users should, therefore, avoid any non git town commands .. which is a bit of a pitty

@pradeepmurugesan
Copy link
Member Author

Hello @kevgo

Thank you for responding.

does indeed invoke the locally installed Git Town binary (the one in ~/go/bin/) via a subshell

Yes.. I tried uninstalling the local installation and ran make cukethis . I can see the test failing with

iagnostic information of failed command

COMMAND: git-town sync
ERROR: exec: "git-town": executable file not found in $PATH
OUTPUT START

OUTPUT END

Run make cukethis. This builds the Git Town binary and executes only the scenario tagged with @this

I am not sure if this is actually building the binary from the code base as I can see the tests are failing without a local installation. Am I missing something here ?

I did a go install before running the test. This made sure the binary is built from the source.

But I still cannot get the logs I added. I use the print statement to print something out. I tried to do a panic when the sync runs. Even then the test fails but the panic stacktrace / message is not printed when I run go install && make cukethis

That's the easiest way to debug. If you prefer to debug interactively in VSCode, please follow the instructions in https://github.com/git-town/git-town/blob/main/docs/DEVELOPMENT.md#debug-end-to-end-tests.

I will try this.. The link says change the path of the test to execute what is the path here.. is it options.Paths = pflag.Args() Can you kindly share an example 🙏

@pradeepmurugesan
Copy link
Member Author

Interestingly when I try to run the binary manually I can see the print statements I added

git-town sync
2025/04/09 22:40:14 Sync command called

[rebase-with-ammend] git fetch --prune --tags
--Pradeep is Syncing branch

Sync command called , Pradeep is Syncing branch

But when I execute an end to end test the above logs are not present in the command output. 🤔

DEVELOPER@feature-1 > git-town sync


[feature-1] git fetch --prune --tags

[feature-1] git merge --no-edit --ff main
Already up to date.

I tried to double check if the test is using the same binary by providing when I run which git-town step. can confirm it points to the same one.

@kevgo
Copy link
Contributor
kevgo commented Apr 9, 2025

The error message is correct. You need to 8000 add ~/go/bin (the directory that go install puts executables in on your machine) to your $PATH environment variable. Otherwise the end-to-end tests cannot find the git-town executable and cannot execute it. This setup step was missing in DEVELOPMENT.md. Apologies for the troubles. I have added this in #4694. Thanks for helping identify this problem! 🙏

@pradeepmurugesan
Copy link
Member Author

But I still cannot get the logs I added. I use the print statement to print something out.

Using fmt.Printf instead of print , I can see the logs when we execute the end to test 👍

@kevgo
Copy link
Contributor
kevgo commented Apr 9, 2025

Yes, the correct way to print in Go is fmt.Println("text") or to print variables fmt.Printf("text %s\n", variable). Here is an overview of the formatting verbs you can use with fmt.Printf: https://pkg.go.dev/fmt

@kevgo
Copy link
Contributor
kevgo commented Apr 9, 2025

The print function is some weird internal thing for the people developing Go itself. Normal users of Go should use the functions in the fmt package. See https://stackoverflow.com/questions/14680255/difference-between-fmt-println-and-println-in-go for some background.

@pradeepmurugesan
Copy link
Member Author
pradeepmurugesan 8000 commented Apr 10, 2025

Thanks for all the pointers.. I tried debugging using the launch config in vs code.. I am able to get the debugging points only up until the subprocess execution starts and after the command is completed..

The debugger is gone when the actual command is invoked.. We cannot debug the binary execution in anyway is it ?

I mean when the test_runner.go says err = subProcess.Run() this will call the installed binary.. We cannot have a break point in the sync_branch.go for example and debug that ?

@kevgo
Copy link
Contributor
kevgo commented Apr 10, 2025

Yes, the debugging setup is primarily intended for debugging the end-to-end tests themselves. They contain some complexity to speed up the suite. Debugging the Git Town executable that's invoked by the tests is probably a bit more involved. I haven’t really gone down that path, since I rarely use the debugger. The Git Town CLI already produces quite detailed output (especially with --verbose), and I usually supplement that with some extra log statements. Combined with small, incremental changes via TDD, that approach tends to be the most efficient for me when working in this codebase. Most of the logic is single-threaded and fairly straightforward.

That said, one possible way to debug the Git Town executable as part of an end-to-end test could be:

  1. Add the step And inspect the repo once the Git test repo is fully set up (just before And I run "git-town ..."). This step outputs the test repo path and pauses the test.
  2. Then you can manually run the Git Town binary in debug mode in that directory.

That approach should work, but requires a fair bit of manual setup per debug session.

Pradeep – thanks again for all your work on this. This ticket touches some of the most complex parts of Git Town, and will require updating around 100 end-to-end tests, which is no small task, and not a good first issue for working on this codebase. I’ve got some bandwidth now. Would it be alright with you if I took a stab at implementing this? If you're close to wrapping this up, I'm also happy to pick up something else from the backlog. Just let me know what you want to do here. Thanks! 🙂

@pradeepmurugesan
Copy link
Member Author

If you're close to wrapping this up

ha ha. No not close at all. I am just scratching the surface :-) . Please feel free to implement this if you have bandwidth..

I will find something else to work on, may be a proper good first issue..

Thank you so much for being so considerate and helpful.. 🙏

@kevgo
Copy link
Contributor
kevgo commented Apr 11, 2025

Please keep scratching! 😃 Git Town can use some help, and the codebase is clean and fun to work on (at least that's one of the goals, haha). I have just tagged some good first issues.

@kevgo kevgo changed the title Syncing stack with rebase strategy sync: support for amended branches Apr 12, 2025
@kevgo
Copy link
Contributor
kevgo commented Apr 15, 2025

Update: This works correctly, even if the branches contain multiple commits and only the last commit gets amended. This test script works properly:

# initialize repo
git init test
cd test
git commit --allow-empty -m "Initial commit"

# create branch feature1
git town hack feature1
touch file1a
git add .
git commit -m "commit 1a"
touch file1b
git add .
git commit -m "commit 1b1"

# create child branch feature2
git town append feature2
touch file2
git add .
git commit -m "commit 2"

# amend the commit on branch1
echo "CHECKPOINT A (before update)"
git log --format="%h %s"  
FEATURE1_OLD=$(git rev-parse feature1)
echo "Old branch: $FEATURE1_OLD"
git checkout feature1
echo "new content" > file1a
git add .
git commit --amend -m "commit 1b2"

# rebase branch feature2
git checkout feature2
git rebase --onto feature1 $FEATURE1_OLD

echo "CHECKPOINT B (after update)"
git log --format="%h %s"

Output:

CHECKPOINT A (before update)
b87e22c commit 2
48b6742 commit 1b1
014c08b commit 1a
98b4fc4 Initial commit

CHECKPOINT B (after update)
422a98c commit 2
04b41a2 commit 1b2
014c08b commit 1a
98b4fc4 Initial commit

branch-2 gets correctly updated and contains the new commit 1b2. The old version of that commit (1b1) is gone. The unchanged commit (1a) still exists.

@kevgo
Copy link
Contributor
kevgo commented Apr 15, 2025

This also works correctly when changing a different commit than the last one in the branch, via interactive rebase. This test script works:

# initialize repo
git init test
cd test
git commit --allow-empty -m "Initial commit"

# create branch branch-1
git town hack branch-1
touch file_1a
git add .
git commit -m "commit-1a"
touch file_1b
git add .
git commit -m "commit-1b1"
touch file_1c
git add .
git commit -m "commit-1c"

# create child branch branch-2
git town append branch-2
touch file_2
git add .
git commit -m "commit-2"

echo "CHECKPOINT 1: branch-2 before interactive rebase"
git log --format="%h %s"  

# change commit-1b via interactive rebase on branch-1
FEATURE1_OLD=$(git rev-parse branch-1)
echo "Old branch: $FEATURE1_OLD"
git checkout branch-1
INITIAL_SHA=$(git log --grep=Initial --format="%h")
git rebase -i $INITIAL_SHA

# you see this:
#
# pick ddd36bb commit-1a
# pick 8d11ec1 commit-1b1
# pick 14c2572 commit-1c
#
# change it to:
# 
# pick ddd36bb commit-1a
# r 8d11ec1 commit-1b1
# pick 14c2572 commit-1c
#
# In the new editor that pops up, change the commit message 
# from "commit-1b1" to "commit-1b2".

echo "CHECKPOINT 2: branch-1 after interactive rebase"
git log --format="%h %s"  

git checkout branch-2

echo "CHECKPOINT 3: branch-2 before sync"
git log --format="%h %s"  

# sync branch branch-2
git rebase --onto branch-1 $FEATURE1_OLD

echo "CHECKPOINT 4: branch-2 after sync"
git log --format="%h %s"

What this test script does is change the commit in the middle of branch-1 (with message commit-1b1). Git also gives commit-1c a new SHA.

Output:

CHECKPOINT 1: branch-2 before interactive rebase
bfb971d commit-2
14c2572 commit-1c
8d11ec1 commit-1b1
ddd36bb commit-1a
488e770 Initial commit

CHECKPOINT 2: branch-1 after interactive rebase
8586447 commit-1c
9c5a2e5 commit-1b2
ddd36bb commit-1a
488e770 Initial commit

CHECKPOINT 3: branch-2 before sync
bfb971d commit-2
14c2572 commit-1c
8d11ec1 commit-1b1
ddd36bb commit-1a
488e770 Initial commit

CHECKPOINT 4: branch-2 after sync
600e84e commit-2
8586447 commit-1c
9c5a2e5 commit-1b2
ddd36bb commit-1a
488e770 Initial commit

At checkpoint 3, branch-2 contains the old commits from before the interactive rebase.
At checkpoint 4, branch-2 now contains the new commits from after the interactive rebase.

@kevgo
Copy link
Contributor
kevgo commented Apr 15, 2025

This also works correctly when squashing commits together via interactive rebase.
This test script works:

# initialize repo
git init test
cd test
git commit --allow-empty -m "Initial commit"

# create branch branch-1
git town hack branch-1
touch file_1a
git add .
git commit -m "commit-1a"
touch file_1b
git add .
git commit -m "commit-1b1"
touch file_1c
git add .
git commit -m "commit-1c"

# create child branch branch-2
git town append branch-2
touch file_2
git add .
git commit -m "commit-2"

echo "CHECKPOINT 1: branch-2 before interactive rebase"
git log --format="%h %s"  

# change commit-1b via interactive rebase on branch-1
FEATURE1_OLD=$(git rev-parse branch-1)
git checkout branch-1
INITIAL_SHA=$(git log --grep=Initial --format="%h")
git rebase -i $INITIAL_SHA

# you see this:
#
# pick 1bfcd1b commit-1a
# pick d35bb45 commit-1b1
# pick 3bcddc5 commit-1c
#
# change it to:
# 
# pick 1bfcd1b commit-1a
# f d35bb45 commit-1b1
# f 3bcddc5 commit-1c

echo "CHECKPOINT 2: branch-1 after interactive rebase"
git log --format="%h %s"  

git checkout branch-2

echo "CHECKPOINT 3: branch-2 before sync"
git log --format="%h %s"  

# sync branch branch-2
git rebase --onto branch-1 $FEATURE1_OLD

echo "CHECKPOINT 4: branch-2 after sync"
git log --format="%h %s"

Output:

CHECKPOINT 1: branch-2 before interactive rebase
11fd166 commit-2
3bcddc5 commit-1c
d35bb45 commit-1b1
1bfcd1b commit-1a
e947e18 Initial commit

CHECKPOINT 2: branch-1 after interactive rebase
ef9c032 commit-1a
e947e18 Initial commit

CHECKPOINT 3: branch-2 before sync
11fd166 commit-2
3bcddc5 commit-1c
d35bb45 commit-1b1
1bfcd1b commit-1a
e947e18 Initial commit

CHECKPOINT 4: branch-2 after sync
44c47e8 commit-2
ef9c032 commit-1a
e947e18 Initial commit

That's all the possible edge cases I can think of right now. This new way of syncing seems pretty robust and dependable.

@kevgo
Copy link
Contributor
kevgo commented Apr 28, 2025

@pradeepmurugesan @stephenwade This is implemented but won't ship for a few more days. If you want, you can use this already by compiling the Git Town binary to use from source:

  • run make install
  • add $HOME/go/bin to your $PATH

This would provide some real-world user testing before rolling this out to the tens of thousands of Git Town users worldwide. I don't use the rebase sync strategy, so I can't test this myself. Thanks!

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#4728)).
-   [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.

4 participants
0