feat(git): Allow checking out a commit instead of a branch

This commit is contained in:
Sam Atkins 2024-06-20 14:46:37 +01:00 committed by Eric Dubé
parent 2c9b1a3ffc
commit 057b3acf00

View File

@ -17,7 +17,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import git from 'isomorphic-git'; import git from 'isomorphic-git';
import { find_repo_root } from '../git-helpers.js'; import { find_repo_root, shorten_hash } from '../git-helpers.js';
import { SHOW_USAGE } from '../help.js'; import { SHOW_USAGE } from '../help.js';
const CHECKOUT = { const CHECKOUT = {
@ -122,7 +122,7 @@ const CHECKOUT = {
return; return;
} }
// Check out a branch // Check out a branch or commit
// TODO: Check out files. // TODO: Check out files.
{ {
if (positionals.length === 0 || positionals.length > 1) { if (positionals.length === 0 || positionals.length > 1) {
@ -130,25 +130,39 @@ const CHECKOUT = {
throw SHOW_USAGE; throw SHOW_USAGE;
} }
const { branches, current_branch } = await get_branch_data(); const { branches, current_branch } = await get_branch_data();
const branch_name = positionals.shift(); const reference = positionals.shift();
if (branch_name === current_branch) { if (reference === current_branch) {
stdout(`Already on '${branch_name}'`); stdout(`Already on '${reference}'`);
return; return;
} }
if (!branches.includes(branch_name)) const old_oid = await git.resolveRef({ fs, dir, gitdir, ref: 'HEAD' });
throw new Error(`Branch '${branch_name}' not found.`);
const oid = await git.resolveRef({ fs, dir, gitdir, ref: reference });
if (!oid)
throw new Error(`Reference '${reference}' not found.`);
await git.checkout({ await git.checkout({
fs, fs,
dir, dir,
gitdir, gitdir,
cache, cache,
ref: branch_name, ref: reference,
force: options.force, force: options.force,
}); });
stdout(`Switched to branch '${branch_name}'`); if (branches.includes(reference)) {
stdout(`Switched to branch '${reference}'`);
} else {
const commit = await git.readCommit({ fs, dir, gitdir, oid });
const commit_title = commit.commit.message.split('\n', 2)[0];
const old_commit = await git.readCommit({ fs, dir, gitdir, oid: old_oid });
const old_commit_title = old_commit.commit.message.split('\n', 2)[0];
stdout(`Previous HEAD position was ${shorten_hash(old_oid)} ${old_commit_title}`);
stdout(`HEAD is now at ${shorten_hash(oid)} ${commit_title}`);
}
} }
} }
}; };