Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable auto local branch creation with config option #894

Merged
merged 3 commits into from
Jan 30, 2023
Merged
Changes from 1 commit
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
Prev Previous commit
git: add git.auto-local-branch
Add a new git.auto-local-branch config option. When set to false, a
remote-tracking branch imported from Git will not automatically create a
local branch target. This is implemented by a new GitSettings struct
that passes Git-related settings from UserSettings.

This behavior is particularly useful in a co-located jj and Git repo,
because a Git remote might have branches that are not of everyday
interest to the user, so it does not make sense to export them as local
branches in Git. E.g. https://github.com/gitster/git, the maintainer's
fork of Git, has 379 branches, most of which are topic branches kept
around for historical reasons, and Git developers wouldn't be expected
to have local branches for each remote-tracking branch.
chooglen committed Jan 30, 2023
commit 3c1532ad6c69781faaf8b86777230955b3bc3073
23 changes: 23 additions & 0 deletions docs/config.md
Original file line number Diff line number Diff line change
@@ -268,6 +268,29 @@ the conflict is done, `jj` assumes that the conflict was only partially resolved
and parses the conflict markers to get the new state of the conflict. The
conflict is considered fully resolved when there are no conflict markers left.

## Git settings

### Automatic local branch creation

By default, when `jj` imports a remote-tracking branch from Git, it also
creates a local branch with the same name. In some repositories, this
may be undesirable, e.g.:

- There is a remote with a lot of historical branches that you don't
want to be exported to the co-located Git repo.
- There are multiple remotes with conflicting views of that branch,
resulting in an unhelpful conflicted state.

You can disable this behavior by setting `git.auto-local-branch` like
so,

git.auto-local-branch = false

Note that this setting may make it easier to accidentally delete remote
branches. Since the local branch isn't created, the remote branch will be
deleted if you push the branch with `jj git push --branch` or `jj git push
--all`.

# Alternative ways to specify configuration settings

Instead of `~/.jjconfig.toml`, the config settings can be located at
8 changes: 7 additions & 1 deletion lib/src/git.rs
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@ use crate::commit::Commit;
use crate::git_backend::NO_GC_REF_NAMESPACE;
use crate::op_store::RefTarget;
use crate::repo::MutableRepo;
use crate::settings::GitSettings;
use crate::view::RefName;

#[derive(Error, Debug, PartialEq)]
@@ -65,6 +66,7 @@ fn prevent_gc(git_repo: &git2::Repository, id: &CommitId) {
pub fn import_refs(
mut_repo: &mut MutableRepo,
git_repo: &git2::Repository,
git_settings: &GitSettings,
) -> Result<(), GitImportError> {
let store = mut_repo.store().clone();
let mut existing_git_refs = mut_repo.view().git_refs().clone();
@@ -141,6 +143,9 @@ pub fn import_refs(
mut_repo.merge_single_ref(&ref_name, old_git_target.as_ref(), new_git_target.as_ref());
// If a git remote-tracking branch changed, apply the change to the local branch
// as well
if !git_settings.auto_local_branch {
continue;
}
if let RefName::RemoteBranch { branch, remote: _ } = ref_name {
mut_repo.merge_single_ref(
&RefName::LocalBranch(branch),
@@ -336,6 +341,7 @@ pub fn fetch(
git_repo: &git2::Repository,
remote_name: &str,
callbacks: RemoteCallbacks<'_>,
git_settings: &GitSettings,
) -> Result<Option<String>, GitFetchError> {
let mut remote =
git_repo
@@ -378,7 +384,7 @@ pub fn fetch(
tracing::debug!("remote.disconnect");
remote.disconnect()?;
tracing::debug!("import_refs");
import_refs(mut_repo, git_repo).map_err(|err| match err {
import_refs(mut_repo, git_repo, git_settings).map_err(|err| match err {
GitImportError::InternalGitError(source) => GitFetchError::InternalGitError(source),
})?;
Ok(default_branch)
25 changes: 25 additions & 0 deletions lib/src/settings.rs
Original file line number Diff line number Diff line change
@@ -33,6 +33,27 @@ pub struct RepoSettings {
_config: config::Config,
}

#[derive(Debug, Clone)]
pub struct GitSettings {
pub auto_local_branch: bool,
}

impl GitSettings {
pub fn from_config(config: &config::Config) -> Self {
GitSettings {
auto_local_branch: config.get_bool("git.auto-local-branch").unwrap_or(true),
}
}
}

impl Default for GitSettings {
fn default() -> Self {
GitSettings {
auto_local_branch: true,
}
}
}

fn get_timestamp_config(config: &config::Config, key: &str) -> Option<Timestamp> {
match config.get_string(key) {
Ok(timestamp_str) => match DateTime::parse_from_rfc3339(&timestamp_str) {
@@ -153,6 +174,10 @@ impl UserSettings {
&self.config
}

pub fn git_settings(&self) -> GitSettings {
GitSettings::from_config(&self.config)
}

pub fn graph_style(&self) -> String {
self.config
.get_string("ui.graph.style")
Loading