isomorphic-git: Fetch all branches that match a pattern, ideas for API enhancements, and some bugs that were found

It seems that if a branch has a disconnected history from the main branch, isomorphic-git fails to check it out. You can see the problem on this repository:

const git = require('isomorphic-git')
const fs = require('fs')

;(async () => {
  await git.fetch({
    fs,
    dir: 'isogit',
    url: 'https://github.com/isomorphic-git/isomorphic-git.git',
  })

  await git.checkout({
    fs,
    dir: 'isogit',
    remote: 'origin',
    ref: 'gh-pages',
  })
})()

The error reported is:

Failed to read git object with oid e1593a418bbf61846ce6f044bd01c9cd3cde2004

If you change the ref from gh-pages to develop, it works fine.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 31 (31 by maintainers)

Most upvoted comments

One way is to get a list of branch names in the repository, filter them, then tell fetch to retrieve them.

Another (perhaps alternate) option would be just to have fetch take a collection of include patterns. That’s what I’m essentially doing anyway. Something like: include: [‘v*’, ‘master’].

I’ll probably end up providing both. Some way to do remote reference discovery that essentially exposes GitRemoteHTTP.discover() to get the capabilities and references of a remote, and modifying “git.fetch” to accept an array of refspec patterns. So it’ll probably end up looking a little more verbose, like refspec: ['+refs/heads/master:refs/remotes/origin/master', '+refs/heads/v*:refs/remotes/origin/v/*']. But it will also read the refspecs from .git/config files, which means it’ll understand if you’ve configured your branch to pull from a different remote than ‘origin’ by default, and things like that.

A remote option for resolveRef;

Ooh! That’s a great idea. That way listBranches and resolveRef work exactly the same way, and it elevates ‘remote’ to a common abstraction. You won’t have to be aware of the filesystem implementation (refs/remotes/${remote}/branch). And now I see I can fix git.checkout by changing it to checkout local branches by default instead of ‘origin’ by default. (A design flaw on my part that made checking out local branches impossible - oops!)

I would also study got. It’s very well done.

While we’re on the topic of cloning/fetching/checking out, is there a way to suppress the progress messages written to stdout?

Computing CRCs
Resolving deltas
percent2	milliseconds2	callsToReadSlice	callsToGetExternal
0%	0	0	0
1%	17	3	0
2%	61	3	0
3%	26	2	0
4%	25	4	0
5%	4	5	0
6%	6	3	0
7%	31	5	0
8%	28	5	0
9%	34	4	0
10%	10	6	0
...
100%	0	2	0
hash	readSlice	offsets	crcs	sort	misc
64	608	2819	10	0	15
by depth:
0	1	2	3	4	5	6	7	8	9	10	11
0	129	68	26	6	0	0	0	0	0	0	0
0	203	320	75	8	0	0	0	0	0	0	0

I had fooled myself into thinking this had to do with orphaned branches because the master and develop branches were pointing to the same commit. I see now that it has to do with any branches that aren’t the same.

It makes sense to me that you only fetch branches on demand. That’s often what you want. What I’m trying to do is grab content out of any branches that match a pattern (e.g., v*). So I need a way to get a list of remote branches so I know which ones to fetch. Currently, the listBranches function only looks for heads. Could you add a function that lists remote branches (or all branches?).

Then I’d be able to iterate over the branches that match the filter and collect the files.

The workaround is to dive into .git/refs/remotes/origin/ myself to find matching branches, but it’s a little crowed in there, so an API method would be much nicer.