Skip to content
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

add fearless rebasing and rename trunk/base to target #40

Merged
merged 1 commit into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions content/docs/features/virtual-branches/branch-lanes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import ImageSection from "@/components/ImageSection"

How do you manage your virtual branches?

The main interface for Virtual Branches are a series of branch lanes. Each lane represents a scope of work that is different than what your current base branch (ie, `origin/master`) looks like. Work that is not yet in production.
The main interface for Virtual Branches are a series of branch lanes. Each lane represents a scope of work that is different than what your current target branch (ie, `origin/master`) looks like. Work that is not yet in production.

This could be a local virtual branch that you're working on, or it could be a virtual branch that was created from a remote branch.

Expand All @@ -27,17 +27,17 @@ An example of working on two branches at the same time, while pending upstream c

The sidebar on the left shows you the stashed virtual branches that you have and the "other" branches that you have available (legacy git branches, remote branches and PRs). All of these branches can be converted into virtual branches by clicking them and then clicking the "Apply" button on the branch view.

### Trunk
### Target

The "Trunk" is the view of the base branch that you've set. It will show you essentially a `git log` of `origin/master` or whatever you set as your base branch, and it will show you if there are any commits upstream that you have not integrated locally yet. We will automatically check for new upstream changes every few minutes, but you can also click the update button to check immediately.
The "Target" is the view of the target branch that you've set. It will show you essentially a `git log` of `origin/master` or whatever you set as your target branch, and it will show you if there are any commits upstream that you have not integrated locally yet. We will automatically check for new upstream changes every few minutes, but you can also click the update button to check immediately.

<ImageSection
width={700}
height={600}
className="mx-auto"
alt="Virtual Branches Example"
src="/img/docs/branch-lanes-02.webp"
subtitle="A screenshot showcasing the Trunk view."
src="/img/docs/merge-upstream.png"
subtitle="A screenshot showcasing the Target view."
/>

### Workspace
Expand Down Expand Up @@ -72,7 +72,7 @@ You can inspect any file change by clicking on the file path. GitButler will exp
subtitle="Inspecting our file change"
/>

Once you have committed work, you will see it at the bottom as a list of commits under a tag that indicates that they are local. If you hit the "Push" button, it will attempt to push these commits to the same remote server that your base branch is on.
Once you have committed work, you will see it at the bottom as a list of commits under a tag that indicates that they are local. If you hit the "Push" button, it will attempt to push these commits to the same remote server that your target branch is on.

If you have authenticated to GitHub, you also have the option to create a Pull Request for that branch automatically.

Expand Down
10 changes: 5 additions & 5 deletions content/docs/features/virtual-branches/butler-flow.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@ However, a decade later, and with a new and more powerful branching toolset, we'
## Overview

- In a nutshell, the basic development cycle is very simple.
- All work is based off a "base branch", which is a representation of released production code.
- All work is based off a "target branch", which is a representation of released production code.
- All work immediately exists in a branch.
- Work can be shared with teammates for review as early as possible.
- All branches that are close to merging can be applied locally for integration testing.
- Branches can be reviewed independently and merged after final review.
- Integrated branches are automatically removed from developer context.

### The Base Branch
### The Target Branch

In stock Git tooling, there is nothing specified as the production branch, no special "trunk". It is only by convention that this is enforced.

In GitButler, virtual branches will not work without the specification of a special "base branch". Everything exists in relation to this special branch, everything that differs from it must be accounted for by being owned by some other branch, until those changes are integrated.
In GitButler, virtual branches will not work without the specification of a special "target branch". Everything exists in relation to this special branch, everything that differs from it must be accounted for by being owned by some other branch, until those changes are integrated.

### Virtual Branches

Once you choose a base branch, everything that is in your working directory and not ignored by the Git ignore specification must be owned by a virtual branch. If you don't have one active, GitButler will automatically create one for you.
Once you choose a target branch, everything that is in your working directory and not ignored by the Git ignore specification must be owned by a virtual branch. If you don't have one active, GitButler will automatically create one for you.

All subsequent changes to your working directory, either by applying other branches or directly modifying files, must be owned by a virtual branch.

Expand All @@ -46,4 +46,4 @@ Merge conflicts are known almost as soon as they occur and can be communicated a

### Maintenance

Virtual branches can remain applied locally until they are merged into your upstream base branch. Once integrated by any fashion (squash merge, rebase, merge), the virtual branch is automatically disposed of, keeping cruft and overhead low.
Virtual branches can remain applied locally until they are merged into your upstream target branch. Once integrated by any fashion (squash merge, rebase, merge), the virtual branch is automatically disposed of, keeping cruft and overhead low.
19 changes: 19 additions & 0 deletions content/docs/features/virtual-branches/commits.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,22 @@ You can also arbitrarily change the order of your commits by dragging and droppi
alt="Moving Commits"
src="/img/docs/commits-09.gif"
/>

## Edit Mode

The other way that you can modify a commit is to go into "Edit Mode". When you click on a commit, there is a button that says "Edit patch". If you click this, GitButler will check out that commit by itself into your working directory (automatically stashing everything else temporarily).

The screen will go into "Edit mode", indicating that you're in a special state where you're focusing on this one commit.

<ImageSection
subtitle="Editing a commit"
width={700}
height={600}
className="mx-auto"
alt="Editing a commit"
src="/img/docs/conflicts-edit-mode.png"
/>

Then you can change whatever you want and when you click "Save and exit", it will amend the commit you were editing and rebase anything on top of it.

This is useful for things like getting feedback on a series and being able to go into the appropriate commit, make the changes and continue, as opposed to squashing work.
45 changes: 22 additions & 23 deletions content/docs/features/virtual-branches/merging.mdx
Original file line number Diff line number Diff line change
@@ -1,47 +1,46 @@
---
title: Merging
title: Rebasing and Conflicts
---

import ImageSection from "@/components/ImageSection"

Conflicts happen sometimes, what to do when we get there?
By default, GitButler rebases the work on your virtual branches when you update your target branch (upstream) work.

So, let's talk a little bit more about merging. Merging in GitButler is a little different than in Git because by default, all applied virtual branches are actually merged in your working directory, as though you had run a `git merge` or `git pull` command.
Often this works just fine and the commits are simply rebased. Occasionally, you will have conflicts with upstream work.

However, it doesn't need to actually make the merge commit and tie those contexts together forever. It can simply do the merge, give you the result and keep track of what you do to it. This allows you to unmerge and remerge at will, as long as the branches merge cleanly.
In this case, GitButler will not do what Git normally does, which is to stop at each conflicted commit and make you fix it before moving on. Instead, it will apply the changes that it can and store the commit as a "conflicted" commit and continue the rebasing process.

The other interesting thing is that you cannot get two branches into a conflicting state while they are both applied, because all code in your working directory has to be owned by something. If you come across a part that overlaps, you have to choose which branch owns it or else unapply one of them.

## Merge Conflicts

You also cannot (currently) apply two virtual branches that conflict with each other. That means that the only way to merge two branches that have conflicts is to land one upstream in your base branch first, then integrate that so that it's your base and then pull those conflicting changes into your working directory and solve them.

In other words, branches can only conflict with upstream changes and you can only resolve one upstream conflicted branch at a time. This is something we will work on changing, but it is a limitation currently.

When you do have an upstream conflicting branch, you can choose to apply it, which will unapply all other branches and apply this one with conflict markers into your files. Your only branch lane will look something like this:
When you go to update from upstream, GitButler will show you all the branches that it will rebase and will let you know if any of them will have conflicts:

<ImageSection
subtitle="One branch has a conflict with the upstream work"
width={700}
height={600}
className="mx-auto"
alt="Viewing Remote Branches"
src="/img/docs/merging-01.avif"
subtitle="A virtual branch in a conflicted state."
src="/img/docs/conflicts-incoming.png"
alt="Conflicts with commits"
/>

While the branch is in this state, you cannot apply other branches or unapply this one. (We are working on a way to abort this state, but right now you cannot).
In this case, when you perform the rebase, that branch will then contain "conflicted" commits. They will be marked in the UI as conflicted and you can click on them to get a "resolve conflict" button to start the resolution process.

You need to resolve each issue, then hit the "Resolve" button next to each file once they are resolved. This is similar to running `git add` on resolved files in a conflicted merge state in stock Git.
<ImageSection
subtitle="Resolving a conflict"
width={700}
height={600}
className="mx-auto"
src="/img/docs/conflicts-conflicted.png"
alt="Conflicts with commits"
/>

Once all the files are marked as resolved, you need to commit the resolved merge. This will write a merge commit with both parents so that you have an updated merge base.
When you click that, GitButler will remove the other virtual branches and other work from your working directory and check out just this commit with it's conflict markers. It will show you a special "edit mode" screen, where you are directly editing this commit.

<ImageSection
subtitle="Resolving a conflict"
width={700}
height={600}
className="mx-auto"
alt="Viewing Remote Branches"
src="/img/docs/merging-02.avif"
subtitle="Now you need to commit your resolution."
src="/img/docs/conflicts-edit.png"
alt="Conflicts with commits"
/>

Once the resolution is committed, you can unapply and apply branches again.
If you want to cancel this conflict resolution, you can just hit 'Cancel' and it will go back to your normal state. If you have fixed all the issues, you can click "Save and Exit" and it will commit the conflict resolution and if needed, rebase any further commits on that branch on top of your new work.
Loading