Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1" /> | |
| <title>Git Visualizer — Interactive Git Core Concepts</title> | |
| <link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='96' height='96' viewBox='0 0 24 24' fill='none' stroke='%236366f1' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8.5 7.5a3.5 3.5 0 0 1 4.5 3.9V14a3 3 0 1 1-1.5-2.6'/%3E%3Cpath d='M6 3a5 5 0 0 0 5 5h3'/%3E%3Cpath d='M2 3v5.5A3.5 3.5 0 0 0 5.5 12H8'/%3E%3Cpath d='M2 12h3a5 5 0 0 1 5 5v3'/%3E%3Cpath d='M10 20v-3a5 5 0 0 1 5-5h3'/%3E%3C/svg%3E" /> | |
| <link rel="stylesheet" href="style.css" /> | |
| <script defer src="script.js"></script> | |
| </head> | |
| <body> | |
| <header class="app-header"> | |
| <div class="brand"> | |
| <div class="logo">⧉</div> | |
| <div class="title"> | |
| <h1>Git Visualizer</h1> | |
| <p>Explore commits, branches, merge, rebase, detached HEAD, blame, issues, and pull requests.</p> | |
| </div> | |
| </div> | |
| <div class="customization"> | |
| <div class="chip"> | |
| <label for="primaryColor">Primary</label> | |
| <input id="primaryColor" type="color" value="#6366f1" /> | |
| </div> | |
| <div class="chip"> | |
| <label for="secondaryColor">Secondary</label> | |
| <input id="secondaryColor" type="color" value="#22c55e" /> | |
| </div> | |
| <div class="chip"> | |
| <label for="themeMode">Theme</label> | |
| <select id="themeMode"> | |
| <option value="system">System</option> | |
| <option value="light">Light</option> | |
| <option value="dark">Dark</option> | |
| </select> | |
| </div> | |
| </div> | |
| </header> | |
| <main class="app"> | |
| <aside class="sidebar"> | |
| <section class="panel"> | |
| <h2>Repository</h2> | |
| <div class="row"> | |
| <div> | |
| <div class="label">Current HEAD</div> | |
| <div id="currentHead" class="value">-</div> | |
| </div> | |
| <div> | |
| <div class="label">Detached</div> | |
| <div id="detachedState" class="value">No</div> | |
| </div> | |
| </div> | |
| <div class="row"> | |
| <div> | |
| <div class="label">Branches</div> | |
| <ul id="branchList" class="list"></ul> | |
| </div> | |
| </div> | |
| <div class="row"> | |
| <div> | |
| <div class="label">Stash</div> | |
| <ul id="stashList" class="list compact"></ul> | |
| </div> | |
| </div> | |
| </section> | |
| <section class="panel"> | |
| <h2>Actions</h2> | |
| <div class="grid"> | |
| <div class="field"> | |
| <label for="commitMsg">Commit message</label> | |
| <input id="commitMsg" type="text" placeholder="Describe your change" /> | |
| </div> | |
| <button id="btnCommit" class="btn primary">Commit</button> | |
| <button id="btnCommitAmend" class="btn ghost">Amend</button> | |
| <button id="btnUndoCommit" class="btn ghost">Undo last commit</button> | |
| </div> | |
| <div class="grid"> | |
| <div class="field"> | |
| <label for="branchName">New branch name</label> | |
| <input id="branchName" type="text" placeholder="feature/..." /> | |
| </div> | |
| <button id="btnCreateBranch" class="btn">Create branch</button> | |
| </div> | |
| <div class="grid"> | |
| <div class="field"> | |
| <label for="switchBranch">Switch to branch</label> | |
| <select id="switchBranch"></select> | |
| </div> | |
| <button id="btnCheckout" class="btn">Checkout</button> | |
| </div> | |
| <div class="grid"> | |
| <div class="field"> | |
| <label for="checkoutCommit">Checkout commit</label> | |
| <select id="checkoutCommit"></select> | |
| </div> | |
| <button id="btnDetach" class="btn warn">Detach HEAD</button> | |
| </div> | |
| <div class="grid"> | |
| <button id="btnMerge" class="btn">Merge selected into current</button> | |
| <button id="btnRebase" class="btn">Rebase current on selected</button> | |
| </div> | |
| <div class="grid"> | |
| <div class="field"> | |
| <label for="mergeTarget">Merge target</label> | |
| <select id="mergeTarget"></select> | |
| </div> | |
| <div class="field"> | |
| <label for="rebaseTarget">Rebase target</label> | |
| <select id="rebaseTarget"></select> | |
| </div> | |
| </div> | |
| <div class="grid"> | |
| <button id="btnStash" class="btn">Stash</button> | |
| <button id="btnStashPop" class="btn">Stash pop</button> | |
| </div> | |
| <div class="grid"> | |
| <button id="btnResetHard" class="btn danger">Reset --hard (to selected)</button> | |
| <select id="resetTarget"></select> | |
| </div> | |
| </section> | |
| <section class="panel"> | |
| <h2>Issues & Pull Requests</h2> | |
| <div class="grid"> | |
| <button id="btnNewIssue" class="btn">New Issue</button> | |
| <button id="btnNewPR" class="btn">New Pull Request</button> | |
| </div> | |
| <div class="row"> | |
| <div> | |
| <div class="label">Issues</div> | |
| <ul id="issuesList" class="list"></ul> | |
| </div> | |
| </div> | |
| <div class="row"> | |
| <div> | |
| <div class="label">Pull Requests</div> | |
| <ul id="prsList" class="list"></ul> | |
| </div> | |
| </div> | |
| </section> | |
| <section class="panel"> | |
| <h2>Blame</h2> | |
| <div class="grid"> | |
| <div class="field"> | |
| <label for="blameCommit">Select commit</label> | |
| <select id="blameCommit"></select> | |
| </div> | |
| <button id="btnBlame" class="btn ghost">Show blame</button> | |
| </div> | |
| <div id="blamePanel" class="code hidden"></div> | |
| </section> | |
| <section class="panel"> | |
| <h2>Demo Scenarios</h2> | |
| <div class="grid"> | |
| <button id="btnDemoBasic" class="btn">Init demo</button> | |
| <button id="btnDemoPR" class="btn">Open PR scenario</button> | |
| </div> | |
| </section> | |
| </aside> | |
| <section class="graph"> | |
| <div class="graph-toolbar"> | |
| <div class="left"> | |
| <button id="btnFit" class="btn ghost">Fit</button> | |
| <button id="btnCenterMain" class="btn ghost">Center main</button> | |
| <button id="btnCenterHead" class="btn ghost">Center HEAD</button> | |
| </div> | |
| <div class="right"> | |
| <span class="legend"><span class="legend-dot"></span> Commits</span> | |
| <span class="legend"><span class="legend-branch"></span> Branch head</span> | |
| <span class="legend"><span class="legend-head"></span> HEAD</span> | |
| </div> | |
| </div> | |
| <div class="canvas-wrapper"> | |
| <svg id="graphSvg" xmlns="http://www.w3.org/2000/svg"></svg> | |
| </div> | |
| </section> | |
| </main> | |
| <footer class="app-footer"> | |
| <div>Tip: Start with “Init demo”, create a branch, make commits, then try Merge and Rebase. Toggle theme and colors above.</div> | |
| <div class="small">Built for interactive learning of core Git concepts.</div> | |
| </footer> | |
| <script> | |
| // Configure CSS variables from inputs (supports "undefined" placeholder too) | |
| const primaryInput = document.getElementById('primaryColor'); | |
| const secondaryInput = document.getElementById('secondaryColor'); | |
| const themeMode = document.getElementById('themeMode'); | |
| const applyVars = () => { | |
| const getOrFallback = (v, fallback) => (!v || v === 'undefined') ? fallback : v; | |
| document.documentElement.style.setProperty('--primary', getOrFallback(primaryInput.value, '#6366f1')); | |
| document.documentElement.style.setProperty('--secondary', getOrFallback(secondaryInput.value, '#22c55e')); | |
| }; | |
| primaryInput.addEventListener('input', applyVars); | |
| secondaryInput.addEventListener('input', applyVars); | |
| themeMode.addEventListener('change', () => { | |
| const mode = themeMode.value; | |
| if (mode === 'system') document.documentElement.removeAttribute('data-theme'); | |
| else document.documentElement.setAttribute('data-theme', mode); | |
| }); | |
| applyVars(); | |
| </script> | |
| <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script> | |
| </body> | |
| </html> |