Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1240,6 +1240,23 @@ export declare class Repository {
* If this repository is bare, then `null` is returned.
*/
workdir(): string | null
/** Retrieve and resolve the reference pointed at by HEAD. */
head(): Reference
/**
* Make the repository HEAD point to the specified reference.
*
* If the provided reference points to a tree or a blob, the HEAD is
* unaltered and an error is returned.
*
* If the provided reference points to a branch, the HEAD will point to
* that branch, staying attached, or become attached if it isn't yet. If
* the branch doesn't exist yet, no error will be returned. The HEAD will
* then be attached to an unborn branch.
*
* Otherwise, the HEAD will be detached and will directly point to the
* commit.
*/
setHead(refname: string): void
/**
* Execute a rev-parse operation against the `spec` listed.
*
Expand Down
28 changes: 28 additions & 0 deletions src/repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,34 @@ impl Repository {
.workdir()
.and_then(|path| util::path_to_js_string(&env, path).ok())
}

#[napi]
/// Retrieve and resolve the reference pointed at by HEAD.
pub fn head(&self, this: Reference<Repository>, env: Env) -> crate::Result<crate::reference::Reference> {
Ok(crate::reference::Reference {
inner: this.share_with(env, |repo| {
repo.inner.head().map_err(crate::Error::from).map_err(|e| e.into())
})?,
})
}

#[napi]
/// Make the repository HEAD point to the specified reference.
///
/// If the provided reference points to a tree or a blob, the HEAD is
/// unaltered and an error is returned.
///
/// If the provided reference points to a branch, the HEAD will point to
/// that branch, staying attached, or become attached if it isn't yet. If
/// the branch doesn't exist yet, no error will be returned. The HEAD will
/// then be attached to an unborn branch.
///
/// Otherwise, the HEAD will be detached and will directly point to the
/// commit.
pub fn set_head(&self, refname: String) -> crate::Result<()> {
self.inner.set_head(&refname)?;
Ok(())
}
}

fn update_submodules(repo: &git2::Repository) -> crate::Result<()> {
Expand Down
25 changes: 25 additions & 0 deletions tests/repository.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,29 @@ describe('Repository', () => {
});
expect(repo.state()).toBe('Clean');
});

it('get head', async () => {
const p = await useFixture('commits');
const repo = await openRepository(p);
const ref = repo.head();
expect(ref.name()).toEqual('refs/heads/main');
expect(ref.shorthand()).toEqual('main');
expect(ref.type()).toEqual('Direct');
expect(ref.target()).toEqual('a01e9888e46729ef4aa68953ba19b02a7a64eb82');
expect(ref.isBranch()).toBe(true);
expect(ref.symbolicTarget()).toBeNull();
});

it('set head', async () => {
const p = await useFixture('revparse');
const repo = await openRepository(p);
repo.setHead('refs/heads/other');
const ref = repo.head();
expect(ref.name()).toEqual('refs/heads/other');
expect(ref.shorthand()).toEqual('other');
expect(ref.type()).toEqual('Direct');
expect(ref.target()).toEqual('b580e5f5030f508a3658a4155f44cdd9754950c5');
expect(ref.isBranch()).toBe(true);
expect(ref.symbolicTarget()).toBeNull();
});
});
Loading