Skip to content
This repository was archived by the owner on Dec 15, 2022. It is now read-only.

Read and write git configuration without repository #2564

Merged
merged 17 commits into from
Nov 20, 2020
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
10 changes: 10 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ jobs:
- name: install dependencies
shell: bash
run: ${APM} ci
- name: configure git
shell: bash
run: |
git config --global user.name Hubot
git config --global user.email [email protected]
- name: run tests
shell: bash
run: ${ATOM} --test test/
Expand Down Expand Up @@ -79,6 +84,11 @@ jobs:
- name: install dependencies
shell: bash
run: sh -c "${APM} ci"
- name: configure git
shell: bash
run: |
git config --global user.name Hubot
git config --global user.email [email protected]
- name: run tests
shell: bash
run: sh -c "${ATOM} --test test/"
Expand Down
14 changes: 12 additions & 2 deletions lib/controllers/git-tab-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -371,9 +371,19 @@ export default class GitTabController extends React.Component {

closeIdentityEditor = () => this.setState({editingIdentity: false})

setUsername = () => this.props.repository.setConfig('user.name', this.usernameBuffer.getText(), {global: true})
setUsername = () => {
const newUsername = this.usernameBuffer.getText();
if (newUsername !== this.props.username) {
this.props.repository.setConfig('user.name', newUsername, {global: true});
}
}

setEmail = () => this.props.repository.setConfig('user.email', this.emailBuffer.getText(), {global: true})
setEmail = () => {
const newEmail = this.emailBuffer.getText();
if (newEmail !== this.props.email) {
this.props.repository.setConfig('user.email', newEmail, {global: true});
}
}

restoreFocus() {
this.refView.map(view => view.setFocus(this.lastFocus));
Expand Down
8 changes: 4 additions & 4 deletions lib/git-shell-out-strategy.js
Original file line number Diff line number Diff line change
Expand Up @@ -1007,12 +1007,12 @@ export default class GitShellOutStrategy {
let output;
try {
let args = ['config'];
if (local || atom.inSpecMode()) { args.push('--local'); }
if (local) { args.push('--local'); }
args = args.concat(option);
output = await this.exec(args);
} catch (err) {
if (err.code === 1) {
// No matching config found
if (err.code === 1 || err.code === 128) {
// No matching config found OR --local can only be used inside a git repository
return null;
} else {
throw err;
Expand All @@ -1025,7 +1025,7 @@ export default class GitShellOutStrategy {
setConfig(option, value, {replaceAll, global} = {}) {
let args = ['config'];
if (replaceAll) { args.push('--replace-all'); }
if (global && !atom.inSpecMode()) { args.push('--global'); }
if (global) { args.push('--global'); }
args = args.concat(option, value);
return this.exec(args, {writeOperation: true});
}
Expand Down
164 changes: 164 additions & 0 deletions lib/models/repository-states/cache/keys.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
class CacheKey {
constructor(primary, groups = []) {
this.primary = primary;
this.groups = groups;
}

getPrimary() {
return this.primary;
}

getGroups() {
return this.groups;
}

removeFromCache(cache, withoutGroup = null) {
cache.removePrimary(this.getPrimary());

const groups = this.getGroups();
for (let i = 0; i < groups.length; i++) {
const group = groups[i];
if (group === withoutGroup) {
continue;
}

cache.removeFromGroup(group, this);
}
}

/* istanbul ignore next */
toString() {
return `CacheKey(${this.primary})`;
}
}

class GroupKey {
constructor(group) {
this.group = group;
}

removeFromCache(cache) {
for (const matchingKey of cache.keysInGroup(this.group)) {
matchingKey.removeFromCache(cache, this.group);
}
}

/* istanbul ignore next */
toString() {
return `GroupKey(${this.group})`;
}
}

export const Keys = {
statusBundle: new CacheKey('status-bundle'),

stagedChanges: new CacheKey('staged-changes'),

filePatch: {
_optKey: ({staged}) => (staged ? 's' : 'u'),

oneWith: (fileName, options) => { // <-- Keys.filePatch
const optKey = Keys.filePatch._optKey(options);
const baseCommit = options.baseCommit || 'head';

const extraGroups = [];
if (options.baseCommit) {
extraGroups.push(`file-patch:base-nonhead:path-${fileName}`);
extraGroups.push('file-patch:base-nonhead');
} else {
extraGroups.push('file-patch:base-head');
}

return new CacheKey(`file-patch:${optKey}:${baseCommit}:${fileName}`, [
'file-patch',
`file-patch:opt-${optKey}`,
`file-patch:opt-${optKey}:path-${fileName}`,
...extraGroups,
]);
},

eachWithFileOpts: (fileNames, opts) => {
const keys = [];
for (let i = 0; i < fileNames.length; i++) {
for (let j = 0; j < opts.length; j++) {
keys.push(new GroupKey(`file-patch:opt-${Keys.filePatch._optKey(opts[j])}:path-${fileNames[i]}`));
}
}
return keys;
},

eachNonHeadWithFiles: fileNames => {
return fileNames.map(fileName => new GroupKey(`file-patch:base-nonhead:path-${fileName}`));
},

allAgainstNonHead: new GroupKey('file-patch:base-nonhead'),

eachWithOpts: (...opts) => opts.map(opt => new GroupKey(`file-patch:opt-${Keys.filePatch._optKey(opt)}`)),

all: new GroupKey('file-patch'),
},

index: {
oneWith: fileName => new CacheKey(`index:${fileName}`, ['index']),

all: new GroupKey('index'),
},

lastCommit: new CacheKey('last-commit'),

recentCommits: new CacheKey('recent-commits'),

authors: new CacheKey('authors'),

branches: new CacheKey('branches'),

headDescription: new CacheKey('head-description'),

remotes: new CacheKey('remotes'),

config: {
_optKey: options => (options.local ? 'l' : ''),

oneWith: (setting, options) => {
const optKey = Keys.config._optKey(options);
return new CacheKey(`config:${optKey}:${setting}`, ['config', `config:${optKey}`]);
},

eachWithSetting: setting => [
Keys.config.oneWith(setting, {local: true}),
Keys.config.oneWith(setting, {local: false}),
],

all: new GroupKey('config'),
},

blob: {
oneWith: sha => new CacheKey(`blob:${sha}`, ['blob']),
},

// Common collections of keys and patterns for use with invalidate().

workdirOperationKeys: fileNames => [
Keys.statusBundle,
...Keys.filePatch.eachWithFileOpts(fileNames, [{staged: false}]),
],

cacheOperationKeys: fileNames => [
...Keys.workdirOperationKeys(fileNames),
...Keys.filePatch.eachWithFileOpts(fileNames, [{staged: true}]),
...fileNames.map(Keys.index.oneWith),
Keys.stagedChanges,
],

headOperationKeys: () => [
Keys.headDescription,
Keys.branches,
...Keys.filePatch.eachWithOpts({staged: true}),
Keys.filePatch.allAgainstNonHead,
Keys.stagedChanges,
Keys.lastCommit,
Keys.recentCommits,
Keys.authors,
Keys.statusBundle,
],
};
Loading