Client topic
Client role
A repository declares its remotes; the client reaches them. GitRemotes
lists, adds, renames, re-points and removes remote declarations, while
GitFileClient clones repositories and exchanges with remotes on their
behalf. Keeping the roles apart means a repository never starts an exchange
and the client never edits objects or references itself.
What the client drives
GitFileClient covers clone and cloneBare, then fetch and push on
an existing GitFileRepository and pull on a GitWorkingRepository.
supportedSchemes exposes the accepted URL schemes as data. The runnable
examples are
example/client.dart, example/remote_client.dart and
example/remote_tags.dart.
Accepted and refused locations
A clone source or remote location is accepted as a local path, Windows drive
and UNC spellings included, as a file://, http://, https:// or
ssh:// URL, or as the scp-like user@host:path form. Everything else is
refused before git starts: an empty value, a value spelled like an option, a
remote helper such as ext::… or fd::…, or a scheme outside the accepted
list.
The client also bounds the transports themselves. It sets
GIT_ALLOW_PROTOCOL to exactly file:http:https:ssh. Git reads that
variable in preference to every protocol.* setting, so a remote already
recorded in the repository, a redirect or a submodule cannot borrow a
transport the client did not accept.
Credentials and prompts
The library supplies no credentials. Git uses the credential helper,
ssh-agent or keys the environment and git configuration already provide.
By default, the process environment sets GIT_TERMINAL_PROMPT=0 and
GCM_INTERACTIVE=never. When no SSH command is configured, the client uses
ssh -oBatchMode=yes, so SSH refuses authentication or host-key prompts.
An SSH command chosen through GIT_SSH_COMMAND, GIT_SSH or
core.sshCommand is preserved without adding batch mode. The client sets
SSH_ASKPASS_REQUIRE=never, but cannot guarantee that a custom command or
credential helper will not prompt. The host must configure those programs
for non-interactive use. Runner environment defaults can also be overridden
explicitly by the caller.
Pull semantics
pull fetches and then merges into the current branch of a
GitWorkingRepository. With no remote and no branch, it follows the
upstream of the current branch. With both, it integrates that remote branch.
With a remote alone, it fetches the current branch from that remote; asking
for a branch without a remote is refused before git runs.
A pull with no branch to follow — a detached HEAD or a current branch without an upstream — fails before any exchange. The outcome is the merge outcome, conflicts included: a conflicted merge is a result, not an exception. The mode only selects which merges the merge half allows; there is no rebase.
fetch and push share the same location rules and the same bounded
environment. A fetch chooses its tags through its tags argument; a push
can carry local tags, force a non-fast-forward update, or record the pushed
branch as the upstream of its remote counterpart.
import 'package:git_engine/git_engine.dart';
import 'package:git_engine/process.dart';
Future<void> main() async {
final GitFileClient client = ProcessGitEngine();
final GitWorkingRepository repository = await client.clone(
'https://example.com/team/project.git',
'/srv/project',
);
await repository.remotes.add(
'upstream',
'ssh://git@example.com/team/project.git',
);
await client.fetch(repository, remote: 'upstream');
final GitMergeResult result = await client.pull(repository);
print(result);
}
Classes
- GitFileClient Client
- Client role over repositories stored on disk: it clones a remote location into a target path, and exchanges with remotes on behalf of those repositories.