feat(git): add interactive rebase and reflog recovery features
This update significantly expands Git functionality by implementing support for advanced workflows, including interactive rebasing and recovering lost commits via the reflog. New logic handles preparing the necessary environment files (todo lists and reword queues) required by Git's internal editors. The frontend components are also updated to expose these new capabilities to the user interface. - Implements full planning and execution flow for interactive rebase - Adds functionality to list and restore commits using the reflog history - Updates Rust backend commands to support advanced git operations
This commit is contained in:
+131
@@ -2786,6 +2786,133 @@
|
||||
max-height: calc(100vh - 32px);
|
||||
overflow: auto;
|
||||
}
|
||||
.interactive-rebase-dialog,
|
||||
.reflog-dialog {
|
||||
grid-template-rows: auto minmax(0, 1fr) auto;
|
||||
width: min(1120px, calc(100vw - 32px));
|
||||
height: min(820px, 100%);
|
||||
}
|
||||
|
||||
.interactive-rebase-body {
|
||||
display: grid;
|
||||
grid-template-rows: auto auto minmax(0, 1fr) auto;
|
||||
align-content: start;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.rebase-base-bar {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(280px, 0.7fr) minmax(260px, 1fr);
|
||||
align-items: end;
|
||||
gap: 16px;
|
||||
padding: 12px 16px;
|
||||
border-bottom: 1px solid var(--color-border-subtle);
|
||||
background: var(--color-surface-dim);
|
||||
}
|
||||
.rebase-base-bar label { display: grid; gap: 5px; color: var(--color-ink-muted); font-size: 12px; }
|
||||
.rebase-base-bar label > span { font-weight: 700; }
|
||||
.rebase-base-bar label strong { color: var(--color-ink); font-family: var(--font-mono); }
|
||||
.rebase-base-bar p { margin: 0 0 4px; color: var(--color-ink-faint); font-size: 12px; line-height: 1.45; }
|
||||
.rebase-plan {
|
||||
display: grid;
|
||||
align-content: start;
|
||||
min-height: 0;
|
||||
padding: 8px;
|
||||
overflow: auto;
|
||||
background: var(--code-surface);
|
||||
}
|
||||
.rebase-plan-row {
|
||||
display: grid;
|
||||
grid-template-columns: auto 112px 64px minmax(0, 1fr);
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
min-height: 48px;
|
||||
padding: 6px 8px;
|
||||
border: 1px solid transparent;
|
||||
border-bottom-color: var(--color-border-subtle);
|
||||
background: var(--code-surface);
|
||||
}
|
||||
.rebase-plan-row:hover { border-color: var(--color-border-subtle); background: var(--code-hover-bg); }
|
||||
.rebase-plan-row.drop { opacity: 0.58; background: var(--code-delete-bg); }
|
||||
.rebase-order-actions { display: inline-flex; gap: 3px; }
|
||||
.rebase-order-actions button {
|
||||
width: 25px;
|
||||
min-height: 25px;
|
||||
padding: 0;
|
||||
border-radius: 5px;
|
||||
background: var(--code-surface-subtle);
|
||||
}
|
||||
.rebase-action { height: 30px; font-family: var(--font-mono); font-weight: 800; }
|
||||
.rebase-action.pick { color: var(--code-add-strong); }
|
||||
.rebase-action.reword { color: var(--code-hunk-text); }
|
||||
.rebase-action.squash, .rebase-action.fixup { color: #96620f; }
|
||||
.rebase-action.drop { color: var(--code-delete-strong); }
|
||||
.rebase-plan-row > code { color: var(--color-accent); font-family: var(--font-mono); font-size: 11px; font-weight: 800; }
|
||||
.rebase-commit-copy { display: grid; gap: 3px; min-width: 0; }
|
||||
.rebase-commit-copy strong { overflow: hidden; color: var(--color-ink); font-size: 12.5px; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.rebase-commit-copy span { color: var(--color-ink-faint); font-size: 10.5px; }
|
||||
.rebase-commit-copy input { height: 30px; font-family: var(--font-mono); font-size: 12px; }
|
||||
.rebase-warning {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
margin: 8px 12px 0;
|
||||
padding: 8px 10px;
|
||||
border: 1px solid rgba(224,160,64,0.25);
|
||||
border-radius: 7px;
|
||||
color: #b87914;
|
||||
background: rgba(224,160,64,0.08);
|
||||
font-size: 12px;
|
||||
}
|
||||
.rebase-warning.error { border-color: rgba(232,96,96,0.28); color: var(--code-delete-text); background: var(--code-delete-bg); }
|
||||
.rebase-footer-actions { display: flex; gap: 8px; }
|
||||
|
||||
.reflog-body { display: grid; grid-template-columns: minmax(340px, 0.8fr) minmax(0, 1.2fr); min-height: 0; overflow: hidden; }
|
||||
.reflog-list-pane { display: grid; grid-template-rows: auto minmax(0, 1fr); min-width: 0; min-height: 0; border-right: 1px solid var(--color-border-subtle); background: var(--app-dialog-chrome); }
|
||||
.reflog-search { position: relative; display: flex; align-items: center; padding: 10px; border-bottom: 1px solid var(--color-border-subtle); }
|
||||
.reflog-search svg { position: absolute; left: 21px; color: var(--color-ink-faint); }
|
||||
.reflog-search input { padding-left: 34px; }
|
||||
.reflog-list { display: grid; align-content: start; min-height: 0; padding: 7px; overflow: auto; }
|
||||
.reflog-list > button {
|
||||
display: grid;
|
||||
justify-content: stretch;
|
||||
gap: 4px;
|
||||
width: 100%;
|
||||
min-height: 70px;
|
||||
padding: 8px 10px;
|
||||
border-color: transparent;
|
||||
border-bottom-color: var(--color-border-subtle);
|
||||
border-radius: 6px;
|
||||
background: transparent;
|
||||
text-align: left;
|
||||
}
|
||||
.reflog-list > button:hover:not(:disabled) { background: var(--color-surface-hover); }
|
||||
.reflog-list > button.active { border-color: rgba(49,95,214,0.3); background: rgba(49,95,214,0.09); }
|
||||
.reflog-list > button strong { overflow: hidden; color: var(--color-ink); font-size: 12px; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.reflog-row-top, .reflog-row-bottom { display: flex; align-items: center; justify-content: space-between; min-width: 0; gap: 8px; color: var(--color-ink-faint); font-size: 10.5px; }
|
||||
.reflog-row-top code { color: var(--color-accent); font-weight: 800; }
|
||||
.reflog-row-bottom code { color: var(--color-ink-dim); }
|
||||
.reflog-detail { display: grid; align-content: start; gap: 14px; min-width: 0; padding: 18px; overflow: auto; }
|
||||
.reflog-detail-head { display: flex; align-items: center; gap: 10px; }
|
||||
.reflog-detail-head > svg { color: var(--color-accent); }
|
||||
.reflog-detail-head h3 { margin: 2px 0 0; color: var(--color-ink); font-size: 17px; }
|
||||
.reflog-detail dl { display: grid; gap: 1px; margin: 0; overflow: hidden; border: 1px solid var(--color-border-subtle); border-radius: 8px; background: var(--color-border-subtle); }
|
||||
.reflog-detail dl > div { display: grid; grid-template-columns: 90px minmax(0, 1fr); gap: 10px; padding: 9px 11px; background: var(--color-surface-raised); }
|
||||
.reflog-detail dt { color: var(--color-ink-faint); font-size: 11px; font-weight: 800; text-transform: uppercase; }
|
||||
.reflog-detail dd { min-width: 0; margin: 0; overflow: hidden; color: var(--color-ink-muted); font-size: 12px; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.reflog-detail dd code { font-family: var(--font-mono); }
|
||||
.reflog-preview { justify-self: start; }
|
||||
.reflog-recovery-card { display: grid; gap: 12px; padding: 14px; border: 1px solid rgba(78,202,118,0.24); border-radius: 10px; background: rgba(78,202,118,0.07); }
|
||||
.reflog-recovery-title { display: flex; align-items: flex-start; gap: 9px; }
|
||||
.reflog-recovery-title > svg { flex: 0 0 auto; color: var(--code-add-strong); }
|
||||
.reflog-recovery-title div { display: grid; gap: 3px; }
|
||||
.reflog-recovery-title strong { color: var(--color-ink); font-size: 13px; }
|
||||
.reflog-recovery-title span { color: var(--color-ink-faint); font-size: 11px; line-height: 1.4; }
|
||||
.reflog-recovery-card label { display: grid; gap: 5px; color: var(--color-ink-faint); font-size: 10.5px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.04em; }
|
||||
.reflog-recovery-card label > div { position: relative; display: flex; align-items: center; }
|
||||
.reflog-recovery-card label svg { position: absolute; left: 10px; color: var(--color-accent); }
|
||||
.reflog-recovery-card label input { padding-left: 33px; font-family: var(--font-mono); text-transform: none; letter-spacing: 0; }
|
||||
.reflog-recovery-card .btn-primary { justify-self: start; }
|
||||
.new-branch-dialog {
|
||||
display: block;
|
||||
width: min(520px, calc(100vw - 32px));
|
||||
@@ -5127,6 +5254,10 @@
|
||||
.file-search-hit { grid-template-columns: auto minmax(0, 1fr); align-items: start; }
|
||||
.file-search-hit .status-badge,
|
||||
.file-search-action { grid-column: 2; justify-self: start; }
|
||||
.rebase-base-bar { grid-template-columns: 1fr; }
|
||||
.rebase-plan-row { grid-template-columns: auto 96px 54px minmax(180px, 1fr); }
|
||||
.reflog-body { grid-template-columns: 1fr; grid-template-rows: minmax(220px, 0.8fr) minmax(0, 1.2fr); }
|
||||
.reflog-list-pane { border-right: none; border-bottom: 1px solid var(--color-border-subtle); }
|
||||
.dialog-files { border-right: none; border-bottom: 1px solid var(--color-border-subtle); }
|
||||
.branch-actions { flex-direction: row; justify-content: flex-start; }
|
||||
.tb-action-label { display: none; }
|
||||
|
||||
Reference in New Issue
Block a user