[Feature Request] Git Branch-Aware Sessions #1297

Closed
opened 2026-02-16 17:30:20 -05:00 by yindo · 5 comments
Owner

Originally created by @digi-anuragk on GitHub (Aug 14, 2025).

Originally assigned to: @thdxr on GitHub.

Problem:

I often work on multiple features, bug fixes, or experiments simultaneously, each in its own git branch. For each of these tasks, I create and save several opencode sessions.

Currently, all saved sessions are stored in a single, global list. When I switch from feature/user-auth to bugfix/payment-gateway, the sessions list shows me everything at once. This becomes very confusing, as I might have similarly named sessions for different branches (e.g., "API test," "debug session"). It forces me to rely on memory or cumbersome naming conventions (like auth-api-test) to identify the correct session for my current branch. This clutters the UI and increases the chances of opening the wrong session.

Proposed solution:

I propose making sessions "git branch aware." The core idea is to associate each saved session with the git branch it was created on. This would enable a more organized and context-sensitive session management system.

Here's how I envision it working:

  1. Automatic Branch Association: When a user saves a session, opencode should automatically capture the name of the current active git branch and store it as metadata alongside the session data. No user intervention should be required for this.

  2. Context-Aware Session View: The UI for viewing and managing sessions should be updated to have this new branch information.

  • Default Filter: By default, the session list should only display the sessions that belong to the currently checked-out git branch. This would provide a clean, relevant view that matches the developer's current context.

  • Categorization/Grouping: The UI should offer a way to view all sessions. In this "all sessions" view, the list should be grouped by branch name. This would provide a clear, organized overview of all saved contexts. For example:

      ▼ feature/user-auth
        - Refactor login logic
        - Test password reset
    
      ▼ bugfix/payment-gateway
        - Debug transaction failure
    
      ▼ master
        -Pre-release check
    
  1. Fallback for Non-Git Projects: If a project is not a Git repository (or has no initialized git history), the system can fall back to the current behavior. Sessions saved in such projects will not have branch data associated with them. They could be displayed under a generic "No Branch" or "Global" category in the "all sessions" view, so that they remain accessible without interfering with the branch-specific workflows.
Originally created by @digi-anuragk on GitHub (Aug 14, 2025). Originally assigned to: @thdxr on GitHub. ## Problem: I often work on multiple features, bug fixes, or experiments simultaneously, each in its own git branch. For each of these tasks, I create and save several opencode sessions. Currently, all saved sessions are stored in a single, global list. When I switch from feature/user-auth to bugfix/payment-gateway, the sessions list shows me everything at once. This becomes very confusing, as I might have similarly named sessions for different branches (e.g., "API test," "debug session"). It forces me to rely on memory or cumbersome naming conventions (like auth-api-test) to identify the correct session for my current branch. This clutters the UI and increases the chances of opening the wrong session. ## Proposed solution: I propose making sessions "git branch aware." The core idea is to associate each saved session with the git branch it was created on. This would enable a more organized and context-sensitive session management system. ### Here's how I envision it working: 1. **Automatic Branch Association:** When a user saves a session, opencode should automatically capture the name of the current active git branch and store it as metadata alongside the session data. No user intervention should be required for this. 2. **Context-Aware Session View:** The UI for viewing and managing sessions should be updated to have this new branch information. - **Default Filter:** By default, the session list should only display the sessions that belong to the currently checked-out git branch. This would provide a clean, relevant view that matches the developer's current context. - **Categorization/Grouping:** The UI should offer a way to view all sessions. In this "all sessions" view, the list should be grouped by branch name. This would provide a clear, organized overview of all saved contexts. For example: ▼ feature/user-auth - Refactor login logic - Test password reset ▼ bugfix/payment-gateway - Debug transaction failure ▼ master -Pre-release check 3. **Fallback for Non-Git Projects:** If a project is not a Git repository (or has no initialized git history), the system can fall back to the current behavior. Sessions saved in such projects will not have branch data associated with them. They could be displayed under a generic "No Branch" or "Global" category in the "all sessions" view, so that they remain accessible without interfering with the branch-specific workflows.
yindo closed this issue 2026-02-16 17:30:20 -05:00
Author
Owner

@fmatsos commented on GitHub (Aug 15, 2025):

Would be a nice feature!

But I see some downsides around Git branches : renaming and rebase. There's no an unique hash (or other) to identify a branch as far as I know.

I asked to GPT-5 some proposals about it, and it seems complicated to implement a portable solution at the first sight :/

Below my question about it:


Question:

I want to associate some information with a Git branch. I cannot rely on the branch name, because it can be renamed. I therefore need to use a unique value, such as a hash.

But if another branch is created from the same original commit, will the hash of each branch be unique?
Also, what happens to this in the case of a branch rebase?


Answer:

Good question — and here’s the key point: in Git, a branch does not have its own “hash”.
A branch is just a ref (refs/heads/foo) pointing to a commit (which does have a hash). So:

  • Two branches created from the same commit will have exactly the same tip hash initially (since they point to the same commit). The hash identifies the commit, not the branch.
  • A rebase rewrites history: all rebased commits get new hashes (different parents ⇒ different IDs). If you were associating information to a commit hash, you would lose that association when history is rewritten (rebase, cherry-pick, amend, etc.).

Therefore: associating information to a branch via a commit hash is neither unique nor stable.


How to have a stable branch identifier?

Git does not have a built-in “branch UUID”. You have a few patterns to choose from, depending on portability and team discipline.

1) Attach info to commits using git notes (and propagate on rebase)

  • Store your metadata as a note attached to the tip commit (or to key commits).
  • Enable note rewriting for history-rewriting commands.
# Choose a dedicated notes namespace
git config notes.rewriteRef refs/notes/branch-meta

# Enable note rewriting on history changes
git config notes.rewrite.rebase true
git config notes.rewrite.amend true
git config notes.rewrite.cherry-pick true

# Add a note to the current tip (example: a “line of dev” UUID)
uuid=$(uuidgen)
git notes --ref=refs/notes/branch-meta add -m "branch-id: $uuid" HEAD

Effect:

  • The note is attached to the commit, not the branch.
  • On rebase, Git copies the note from the original commit to the new commit (thanks to notes.rewrite.* config).
  • Limitation: if two branches start from the same commit, they initially share the same note. You can update the note on each branch tip after they diverge.

Best when: you want a 100% Git-native solution, without server hooks, and you’re fine with the info following commits rather than branch names.


2) Use a “companion ref” (stable UUID) that follows the branch

Idea: generate a UUID independent of the branch name, and maintain a companion ref that follows the branch’s tip.

  • On branch creation, generate a UUID and store it (in local/shared config):
uuid=$(uuidgen)
git config "branch.my-feature.uuid" "$uuid"
git update-ref "refs/branch-id/$uuid" "$(git rev-parse my-feature)"
  • On each branch update (push, fast-forward, merge, rebase), a server-side hook (or local script if solo) updates the companion ref:

Example hooks/update (server-side, simplified):

#!/bin/sh
refname="$1"; old="$2"; new="$3"

case "$refname" in
  refs/heads/*)
    branch="${refname#refs/heads/}"
    uuid=$(git config "branch.$branch.uuid")
    if [ -n "$uuid" ]; then
      git update-ref "refs/branch-id/$uuid" "$new"
    fi
  ;;
esac

Effect:

  • You get a stable identifier (UUID), not tied to the branch name, unchanged on rename or rebase.
  • To retrieve the info, read refs/branch-id/<uuid> (or keep the branch→UUID mapping in your tool’s config/DB).

Best when: you want a true “line of development” identity independent of branch name and history rewrites — ideal for CI/CD or dashboards. Requires a small hook.


3) Versioned identity file (e.g., .branch-id) with merge strategy

Create a file containing a UUID at branch birth (e.g., dev/.branch-id). Because rebases copy file contents, the UUID survives.
You can:

  • place it in a branch-specific path (if monorepo/tooling allows),
  • or define a merge driver (merge=ours) to prevent it from leaking into other branches.

Effect:

  • Simple, pure Git, survives rebase.
  • Limitation: may propagate to other branches on merges unless merge behavior is locked down. Two branches starting from the same commit will share the same file until regenerated.

Best when: you want zero infra/hooks and accept some discipline with .gitattributes.


Summary (direct answers)

  • “Will two branches created from the same original commit have unique hashes?”
    No. They will share the same commit hash until one advances. The hash identifies the commit, not the branch.

  • “What happens in case of a rebase?”
    Rebased commits get new hashes. Any association based on commit IDs breaks, unless you use a mechanism that rewrites the metadata alongside (e.g., git notes with notes.rewrite.*) or you tie your metadata to the branch via a companion ref.


Practical recommendation

  • If you control the Git server: Option 2 (companion ref + hook)
    → a UUID per line of development, stable for life, independent of branch name and robust to rebases.

  • Otherwise: Option 1 (git notes + rewrite)
    → native, no infra, works well if you refresh the note on each branch tip and enable note rewriting.

@fmatsos commented on GitHub (Aug 15, 2025): Would be a nice feature! But I see some downsides around Git branches : renaming and rebase. There's no an unique hash (or other) to identify a branch as far as I know. I asked to GPT-5 some proposals about it, and it seems complicated to implement a portable solution at the first sight :/ Below my question about it: --- **Question:** I want to associate some information with a Git branch. I cannot rely on the branch name, because it can be renamed. I therefore need to use a unique value, such as a hash. But if another branch is created from the same original commit, will the hash of each branch be unique? Also, what happens to this in the case of a branch rebase? --- **Answer:** Good question — and here’s the key point: **in Git, a branch does not have its own “hash”**. A branch is just a **ref** (`refs/heads/foo`) pointing to a **commit** (which *does* have a hash). So: - **Two branches created from the same commit will have exactly the same tip hash** initially (since they point to the same commit). The hash identifies the commit, not the branch. - **A rebase rewrites history**: all rebased commits get **new hashes** (different parents ⇒ different IDs). If you were associating information to a commit hash, you would lose that association when history is rewritten (rebase, cherry-pick, amend, etc.). Therefore: **associating information to a branch via a commit hash is neither unique nor stable**. --- ## How to have a stable branch identifier? Git does **not** have a built-in “branch UUID”. You have a few patterns to choose from, depending on portability and team discipline. ### 1) Attach info to *commits* using `git notes` (and propagate on rebase) - Store your metadata as a **note** attached to the tip commit (or to key commits). - Enable **note rewriting** for history-rewriting commands. ```bash # Choose a dedicated notes namespace git config notes.rewriteRef refs/notes/branch-meta # Enable note rewriting on history changes git config notes.rewrite.rebase true git config notes.rewrite.amend true git config notes.rewrite.cherry-pick true # Add a note to the current tip (example: a “line of dev” UUID) uuid=$(uuidgen) git notes --ref=refs/notes/branch-meta add -m "branch-id: $uuid" HEAD ``` **Effect:** - The note is **attached to the commit**, not the branch. - On **rebase**, Git copies the note from the original commit to the new commit (thanks to `notes.rewrite.*` config). - **Limitation:** if two branches start from the same commit, they initially share the same note. You can update the note on each branch tip after they diverge. **Best when**: you want a 100% Git-native solution, without server hooks, and you’re fine with the info following commits rather than branch names. --- ### 2) Use a “companion ref” (stable UUID) that follows the branch Idea: generate a **UUID independent of the branch name**, and maintain a **companion ref** that follows the branch’s tip. - On branch creation, generate a UUID and store it (in local/shared config): ```bash uuid=$(uuidgen) git config "branch.my-feature.uuid" "$uuid" git update-ref "refs/branch-id/$uuid" "$(git rev-parse my-feature)" ``` - **On each branch update** (push, fast-forward, merge, rebase), a **server-side hook** (or local script if solo) updates the companion ref: Example `hooks/update` (server-side, simplified): ```bash #!/bin/sh refname="$1"; old="$2"; new="$3" case "$refname" in refs/heads/*) branch="${refname#refs/heads/}" uuid=$(git config "branch.$branch.uuid") if [ -n "$uuid" ]; then git update-ref "refs/branch-id/$uuid" "$new" fi ;; esac ``` **Effect:** - You get a **stable identifier (UUID)**, **not** tied to the branch name, **unchanged** on rename or rebase. - To retrieve the info, read `refs/branch-id/<uuid>` (or keep the branch→UUID mapping in your tool’s config/DB). **Best when**: you want a **true “line of development” identity** independent of branch name and history rewrites — ideal for CI/CD or dashboards. Requires a small hook. --- ### 3) Versioned identity file (e.g., `.branch-id`) with merge strategy Create a file containing a UUID at branch birth (e.g., `dev/.branch-id`). Because rebases copy file contents, the UUID survives. You can: - place it in a branch-specific path (if monorepo/tooling allows), - or define a **merge driver** (`merge=ours`) to prevent it from leaking into other branches. **Effect:** - Simple, pure Git, survives rebase. - **Limitation:** may propagate to other branches on merges unless merge behavior is locked down. Two branches starting from the same commit will share the same file until regenerated. **Best when**: you want zero infra/hooks and accept some discipline with `.gitattributes`. --- ## Summary (direct answers) - **“Will two branches created from the same original commit have unique hashes?”** No. They will share the same commit hash until one advances. The hash identifies the commit, not the branch. - **“What happens in case of a rebase?”** Rebased commits get **new hashes**. Any association based on commit IDs breaks, unless you use a mechanism that rewrites the metadata alongside (e.g., `git notes` with `notes.rewrite.*`) or you tie your metadata to the branch via a companion ref. --- ## Practical recommendation - If you control the Git server: **Option 2 (companion ref + hook)** → a **UUID per line of development**, stable for life, independent of branch name and robust to rebases. - Otherwise: **Option 1 (git notes + rewrite)** → native, no infra, works well if you refresh the note on each branch tip and enable note rewriting.
Author
Owner

@digi-anuragk commented on GitHub (Aug 15, 2025):

Just a thought...

hmmm 🤔, so much work just to automate the thing.

Maybe we can give another option to change the root branch to some other branch, because if we are coding these features we will anyways have some git things in the code, so maybe I was thinking just to change the branch metadata to new branch for the sessions.

@digi-anuragk commented on GitHub (Aug 15, 2025): _Just a thought..._ hmmm 🤔, so much work just to automate the thing. Maybe we can give another option to change the root branch to some other branch, because if we are coding these features we will anyways have some git things in the code, so maybe I was thinking just to change the branch metadata to new branch for the sessions.
Author
Owner

@justindonnaruma commented on GitHub (Aug 19, 2025):

#2067 is related - But I think if we did it by folder you launched OpenCode in, and stored history in .opencode/histories with a name based on the folder path you launched OpenCode it, that would work in general.

@justindonnaruma commented on GitHub (Aug 19, 2025): #2067 is related - But I think if we did it by folder you launched OpenCode in, and stored history in ``` .opencode/histories ``` with a name based on the folder path you launched OpenCode it, that would work in general.
Author
Owner

@rekram1-node commented on GitHub (Aug 19, 2025):

@justindonnaruma we already do that but we store in ~/.local/share/opencode/project/.... where each project is related to the path of your project

example:

$ ls ~/.local/share/opencode/project
...
Users-aidencline-development-models-dev
Users-aidencline-development-opencode
Users-aidencline-development-opencode-dev
Users-aidencline-development-opencode3
Users-aidencline-development-opentui
...
@rekram1-node commented on GitHub (Aug 19, 2025): @justindonnaruma we already do that but we store in `~/.local/share/opencode/project/....` where each project is related to the path of your project example: ``` $ ls ~/.local/share/opencode/project ... Users-aidencline-development-models-dev Users-aidencline-development-opencode Users-aidencline-development-opencode-dev Users-aidencline-development-opencode3 Users-aidencline-development-opentui ... ```
Author
Owner

@rekram1-node commented on GitHub (Dec 27, 2025):

[automated] Closing due to 90+ days of inactivity. Feel free to reopen if you still need this!

@rekram1-node commented on GitHub (Dec 27, 2025): [automated] Closing due to 90+ days of inactivity. Feel free to reopen if you still need this!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#1297