Skip to content

Commit

Permalink
stub the ref-binary ops
Browse files Browse the repository at this point in the history
  • Loading branch information
gulbanana committed Mar 22, 2024
1 parent 5b42440 commit a720edb
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 13 deletions.
2 changes: 1 addition & 1 deletion DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Consequently, the commands available for a branch as displayed in the UI have po
Multiple-dispatch commands:
1) "Move": Drop local branch onto revision. Sets the ref to a commit, potentially de- or re-syncing it.
2) "Track": Drop remote branch onto local of the same name.
3) "Delete": Drag any branch out, with polymorphic effect (see above).
3) "Delete": Drag almost any branch out, with polymorphic effect (see above).

Displaying the branch state is a bit fuzzy. The idea is to convey the most useful bits of information at
a glance, and leave the rest to tooltips or context menus. Most branches display in the
Expand Down
2 changes: 2 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ These changes may or may not be implemented in the future.
- rename
- delete
* feat: create/delete tags? even moving them is implemented in the backend, but may be a bad idea
* feat: backout rev[s]
* feat: obslog stuff - maybe just "show historical versions" in the log? they should be immutable, and we'd want to be able to reinstate one (as a copy)
* feat: more settings
- log revsets
* design: decide whether to remove edit menu and maybe add others
Expand Down
46 changes: 40 additions & 6 deletions src/mutators/BinaryMutator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { ChangeId } from "../messages/ChangeId";
import type { CommitId } from "../messages/CommitId";
import RevisionMutator from "./RevisionMutator";
import ChangeMutator from "./ChangeMutator";
import BranchMutator from "./RefMutator";

export type RichHint = (string | ChangeId | CommitId)[];
export type Eligibility = { type: "yes", hint: RichHint } | { type: "maybe", hint: string } | { type: "no" };
Expand Down Expand Up @@ -37,7 +38,13 @@ export default class BinaryMutator {

// can't change our view of remote branches
if (from.type == "Ref" && from.ref.type == "RemoteBranch") {
return { type: "maybe", hint: "(branch is remote)" };
if (from.ref.is_tracked && from.ref.is_absent) {
return { type: "maybe", hint: "(branch is deleted)" };
}
// we allow deleting of all other branch types, which might be a good enough reason to move them
// else {
// return { type: "maybe", hint: "(branch is remote)" };
// }
}

// can change these listed things (XXX add modes?)
Expand Down Expand Up @@ -103,20 +110,40 @@ export default class BinaryMutator {
if (this.#from.header.parent_ids.length == 1) {
return { type: "yes", hint: [`Restoring changes at ${this.#from.path.relative_path} from parent `, this.#from.header.parent_ids[0]] };
} else {
return { type: "maybe", hint: "Can't restore: revision has multiple parents." };
return { type: "maybe", hint: "Can't restore (revision has multiple parents)" };
}
}
}

if (this.#from.type == "Ref" && this.#from.ref.type != "Tag") {
if (this.#to.type == "Revision") {
// local -> rev: set
if (this.#to.type == "Revision" && this.#from.ref.type == "LocalBranch") {
if (this.#to.header.id.change.hex == this.#from.header.id.change.hex) {
return { type: "no" };
} else {
return { type: "yes", hint: [`Moving branch ${this.#from.ref.branch_name} to `, this.#to.header.id.change] };
}
} else if (this.#to.type == "Ref" && this.#to.ref.type != "Tag" && this.#from.ref.branch_name == this.#to.ref.branch_name) {
return { type: "yes", hint: [`Resetting branch ${this.#from.ref.branch_name} to remote`] };
}

// remote -> local: track
else if (this.#to.type == "Ref" && this.#to.ref.type == "LocalBranch" &&
this.#from.ref.type == "RemoteBranch" && this.#from.ref.branch_name == this.#to.ref.branch_name) {
if (this.#from.ref.is_tracked) {
return { type: "maybe", hint: "(already tracked)" };
} else {
return { type: "yes", hint: [`Tracking remote branch ${this.#from.ref.branch_name}`] };
}
}

// anything -> anywhere: delete
else if (this.#to.type == "Repository") {
if (this.#from.ref.type == "LocalBranch") {
return { type: "yes", hint: [`Deleting branch ${this.#from.ref.branch_name}`] };
} else {
return {
type: "yes", hint: [`Deleting remote branch ${this.#from.ref.branch_name}@${this.#from.ref.remote_name}`]
};
}
}
}

Expand Down Expand Up @@ -168,9 +195,16 @@ export default class BinaryMutator {
}

if (this.#from.type == "Ref") {
if (this.#to.type == "Revision" || (this.#to.type == "Ref" && this.#to.ref.type != "Tag")) {
if (this.#to.type == "Revision") {
// point ref to revision
mutate<MoveRef>("move_ref", { to_id: this.#to.header.id, ref: this.#from.ref });
return;
} else if (this.#to.type == "Ref" && this.#from.ref.type == "RemoteBranch") {
// track remote branch with existing local
new BranchMutator(this.#from.ref).onTrack();
} else if (this.#to.type == "Repository") {
// various kinds of total or partial deletion
new BranchMutator(this.#from.ref).onDelete();
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/objects/BranchObject.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@
}
</script>

<Object {operand} {label} conflicted={ref.has_conflict} let:context let:hint>
<Zone {operand} let:target>
<Object {operand} {label} conflicted={ref.has_conflict} let:context let:hint={dragHint}>
<Zone {operand} let:target let:hint={dropHint}>
<Chip {context} {target} {disconnected} {tip}>
<Icon name="git-branch" state={context ? null : state} />
<span>{hint ?? label}</span>
<span>{dragHint ?? dropHint ?? label}</span>
</Chip>
</Zone>
</Object>
3 changes: 0 additions & 3 deletions src/objects/RevisionObject.svelte
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
<script lang="ts">
import type { RevHeader } from "../messages/RevHeader";
import type { CheckoutRevision } from "../messages/CheckoutRevision";
import type { CreateRevision } from "../messages/CreateRevision";
import type { Operand } from "../messages/Operand";
import { currentTarget, revisionSelectEvent } from "../stores.js";
import { mutate } from "../ipc";
import IdSpan from "../controls/IdSpan.svelte";
import BranchObject from "./BranchObject.svelte";
import Object from "./Object.svelte";
Expand Down

0 comments on commit a720edb

Please sign in to comment.