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
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,16 @@ Get the target of the given reference.

Returns the string target of the given reference.

### Repository.getRemoteHead([remoteName])

Get the branch that a remote's `HEAD` points to — i.e., the remote's default
branch. This is the equivalent of `git symbolic-ref refs/remotes/<remoteName>/HEAD`.

`remoteName` - The string name of the remote (default: `origin`).

Returns the string reference name (e.g. `refs/remotes/origin/master`), or
`null` if the remote has no `HEAD` reference.

### Repository.getShortHead()

Get a possibly shortened version of value returns by `getHead()`. This will
Expand All @@ -220,6 +230,16 @@ include ignored paths.
Returns an integer status number if a path is specified and returns an object
with path keys and integer status values if no path is specified.

### Repository.getSymbolicRefTarget(ref)

Get the name of the reference that a symbolic reference points to, without
resolving it any further. This is the equivalent of `git symbolic-ref <ref>`.

`ref` - The string reference.

Returns the string name of the reference that `ref` points to, or `null` if
`ref` does not exist or is not a symbolic reference.

### Repository.getUpstreamBranch([branch])

Get the upstream branch of the given branch.
Expand Down
1 change: 1 addition & 0 deletions spec/fixtures/develop.git/HEAD
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ref: refs/heads/develop
9 changes: 9 additions & 0 deletions spec/fixtures/develop.git/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
[branch "develop"]
remote = origin
merge = refs/heads/develop
Binary file added spec/fixtures/develop.git/index
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
xKÊÉOR02fHË,*.QÈÉÌKå*NMÎÏK°¥A
m
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
xmŽMjÃ0…»Ö)æ’<ã±!„r„\`lš@meL{üˆdÛ·x‹ÞÏ\–ån#~XU… ™<'¢Œ! L#INQCOˆœrûÐËì6©º 4 O”ãc‡œ}ôcçI5µ46² “Ýn¥ÂUGk~Ö?Y¶=Ìe9AàÁóØ…ˆðéÙ{×h;fZákMUá²o¥¿ïvÛ§³¼hzÁêöO…{è\Öï*÷÷LFË
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
xmQ
Â0DýÎ)rKÒvI"<‚H·-˜¦Ä-z|—úëÏÀ<˜7XržY[®DÚØÎô<Æ4&èÚ Jë[@èÑBRqãG©úF/Ö'–èóú¤K>‹Ð:Ûöúhœ1J¨1U}Y¦Jo}ÝÖ²Èö>óc‡¸Ói‡ÍBüG¡Ò\åígR_ÇJ9ˆ
Expand Down
1 change: 1 addition & 0 deletions spec/fixtures/develop.git/refs/heads/develop
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
41d3f5ab722c21457592142598d5d1e749927e61
1 change: 1 addition & 0 deletions spec/fixtures/develop.git/refs/remotes/origin/HEAD
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ref: refs/remotes/origin/develop
1 change: 1 addition & 0 deletions spec/fixtures/develop.git/refs/remotes/origin/develop
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
41d3f5ab722c21457592142598d5d1e749927e61
52 changes: 49 additions & 3 deletions spec/git-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -813,9 +813,6 @@ describe('git', () => {
const filePath = path.join(repo.getWorkingDirectory(), 'a.txt')
fs.writeFileSync(filePath, 'first line is different', 'utf8')

let resolve;
let promise = new Promise(r => resolve = r)

await execCommands([`cd ${repoDirectory}`, 'git add a.txt'])

diffs = repo.getLineDiffs('a.txt', 'first line is different', {useIndex: true})
Expand Down Expand Up @@ -1037,6 +1034,55 @@ describe('git', () => {
})
})

describe('.getSymbolicRefTarget(refName)', () => {
describe('when the reference is symbolic', () => {
it('returns the name of the reference it points to', () => {
repo = git.open(path.join(__dirname, 'fixtures/master.git'))
expect(repo.getSymbolicRefTarget('HEAD')).toBe('refs/heads/master')

repo = git.open(path.join(__dirname, 'fixtures/references.git'))
expect(repo.getSymbolicRefTarget('refs/remotes/origin/HEAD')).toBe('refs/remotes/origin/master')
expect(repo.getSymbolicRefTarget('refs/remotes/upstream/HEAD')).toBe('refs/remotes/origin/master')
})
})

describe('when the reference is direct (non-symbolic)', () => {
it('returns null', () => {
repo = git.open(path.join(__dirname, 'fixtures/master.git'))
expect(repo.getSymbolicRefTarget('refs/heads/master')).toBe(null)
})
})

describe('when the reference does not exist', () => {
it('returns null', () => {
repo = git.open(path.join(__dirname, 'fixtures/master.git'))
expect(repo.getSymbolicRefTarget('refs/heads/nonexistent')).toBe(null)
})
})
})

describe('.getRemoteHead([remoteName])', () => {
let repo2
beforeEach(() => {
repo = git.open(path.join(__dirname, 'fixtures/references.git'))
repo2 = git.open(path.join(__dirname, 'fixtures/develop.git'))
})

it('defaults to the "origin" remote', () => {
expect(repo.getRemoteHead()).toBe('refs/remotes/origin/master')
})

it("returns the branch that the given remote's HEAD points to", () => {
expect(repo.getRemoteHead('origin')).toBe('refs/remotes/origin/master')
expect(repo.getRemoteHead('upstream')).toBe('refs/remotes/origin/master')
expect(repo2.getRemoteHead('origin')).toBe('refs/remotes/origin/develop')
})

it('returns null when the remote has no HEAD reference', () => {
expect(repo.getRemoteHead('nonexistent')).toBe(null)
})
})

if (process.env.CI) {
// NOTE: Testing a submodule requires that you be able to add one defined
// at a path on disk. This is disallowed by default these days as a
Expand Down
25 changes: 25 additions & 0 deletions src/binding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,30 @@ Napi::Value Repository::GetStatusForPath(const Napi::CallbackInfo& info) {
}
}

Napi::Value Repository::GetSymbolicRefTarget(const Napi::CallbackInfo& info) {
auto env = info.Env();
Napi::HandleScope scope(env);

if (info.Length() < 1) return env.Null();
CHECK(info[0].IsString(), "Expected string as first argument", env);

std::string refName(info[0].As<Napi::String>());
git_reference* ref = NULL;

if (git_reference_lookup(&ref, GetRepository(info), refName.c_str()) != GIT_OK) {
return env.Null();
}

Napi::Value result = env.Null();
if (git_reference_type(ref) == GIT_REFERENCE_SYMBOLIC) {
const char* target = git_reference_symbolic_target(ref);
if (target) result = Napi::String::New(env, target);
}

git_reference_free(ref);
return result;
}

Napi::Value Repository::CheckoutHead(const Napi::CallbackInfo& info) {
auto env = info.Env();
Napi::HandleScope scope(env);
Expand Down Expand Up @@ -1210,6 +1234,7 @@ void Repository::Init(Napi::Env env, Napi::Object exports) {
InstanceMethod<&Repository::GetStatus>("getStatus", napi_default_method),
InstanceMethod<&Repository::GetStatusForPath>("getStatusForPath", napi_default_method),
InstanceMethod<&Repository::GetStatusAsync>("getStatusAsync", napi_default_method),
InstanceMethod<&Repository::GetSymbolicRefTarget>("getSymbolicRefTarget", napi_default_method),
InstanceMethod<&Repository::CheckoutHead>("checkoutHead", napi_default_method),
InstanceMethod<&Repository::GetReferenceTarget>("getReferenceTarget", napi_default_method),
InstanceMethod<&Repository::GetDiffStats>("getDiffStats", napi_default_method),
Expand Down
1 change: 1 addition & 0 deletions src/binding.hh
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ private:
Napi::Value GetStatus(const Napi::CallbackInfo& info);
Napi::Value GetStatusAsync(const Napi::CallbackInfo& info);
Napi::Value GetStatusForPath(const Napi::CallbackInfo& info);
Napi::Value GetSymbolicRefTarget(const Napi::CallbackInfo& info);
Napi::Value CheckoutHead(const Napi::CallbackInfo& info);
Napi::Value GetReferenceTarget(const Napi::CallbackInfo& info);
Napi::Value GetDiffStats(const Napi::CallbackInfo& info);
Expand Down
4 changes: 4 additions & 0 deletions src/git.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ Repository.prototype.getUpstreamBranch = function (branch) {
return `refs/remotes/${branchRemote}/${shortBranchMerge}`
}

Repository.prototype.getRemoteHead = function (remoteName = 'origin') {
return this.getSymbolicRefTarget(`refs/remotes/${remoteName}/HEAD`)
}

Repository.prototype.getAheadBehindCount = function (branch = 'HEAD') {
if (branch !== 'HEAD' && !branch.startsWith('refs/heads/')) {
branch = `refs/heads/${branch}`
Expand Down
Loading