diff --git a/pass/AppDelegate.swift b/pass/AppDelegate.swift
index c12fd6e..a09a02c 100644
--- a/pass/AppDelegate.swift
+++ b/pass/AppDelegate.swift
@@ -10,6 +10,7 @@ import UIKit
import CoreData
import SVProgressHUD
import passKit
+import SwiftyUserDefaults
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
@@ -33,6 +34,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
self.perform(#selector(postSearchNotification), with: nil, afterDelay: 0.4)
}
}
+
+ // Assign default values to global settings.
+ SharedDefaults.register(defaults: [DefaultsKeys.gitBranchName._key: "master"])
+
return true
}
diff --git a/pass/Base.lproj/Main.storyboard b/pass/Base.lproj/Main.storyboard
index 03dbfe5..08afe1e 100644
--- a/pass/Base.lproj/Main.storyboard
+++ b/pass/Base.lproj/Main.storyboard
@@ -381,10 +381,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -416,7 +445,7 @@
-
+
@@ -466,6 +495,7 @@
+
diff --git a/pass/Controllers/GitServerSettingTableViewController.swift b/pass/Controllers/GitServerSettingTableViewController.swift
index 7c322b4..0410a55 100644
--- a/pass/Controllers/GitServerSettingTableViewController.swift
+++ b/pass/Controllers/GitServerSettingTableViewController.swift
@@ -14,6 +14,7 @@ class GitServerSettingTableViewController: UITableViewController {
@IBOutlet weak var gitURLTextField: UITextField!
@IBOutlet weak var usernameTextField: UITextField!
+ @IBOutlet weak var branchNameTextField: UITextField!
@IBOutlet weak var authSSHKeyCell: UITableViewCell!
@IBOutlet weak var authPasswordCell: UITableViewCell!
let passwordStore = PasswordStore.shared
@@ -51,6 +52,7 @@ class GitServerSettingTableViewController: UITableViewController {
gitURLTextField.text = url.absoluteString
}
usernameTextField.text = SharedDefaults[.gitUsername]
+ branchNameTextField.text = SharedDefaults[.gitBranchName]
sshLabel = authSSHKeyCell.subviews[0].subviews[0] as? UILabel
checkAuthenticationMethod(method: authenticationMethod)
authSSHKeyCell.accessoryType = .detailButton
@@ -77,6 +79,7 @@ class GitServerSettingTableViewController: UITableViewController {
// try to clone
let gitRepostiroyURL = gitURLTextField.text!.trimmed
let username = usernameTextField.text!
+ let branchName = branchNameTextField.text!
let auth = authenticationMethod
SVProgressHUD.setDefaultMaskType(.black)
@@ -100,6 +103,7 @@ class GitServerSettingTableViewController: UITableViewController {
do {
try self.passwordStore.cloneRepository(remoteRepoURL: URL(string: gitRepostiroyURL)!,
credential: gitCredential,
+ branchName: branchName,
requestGitPassword: self.requestGitPassword,
transferProgressBlock: { (git_transfer_progress, stop) in
DispatchQueue.main.async {
@@ -114,6 +118,7 @@ class GitServerSettingTableViewController: UITableViewController {
DispatchQueue.main.async {
SharedDefaults[.gitURL] = URL(string: gitRepostiroyURL)
SharedDefaults[.gitUsername] = username
+ SharedDefaults[.gitBranchName] = branchName
SharedDefaults[.gitAuthenticationMethod] = auth
SVProgressHUD.dismiss()
let savePassphraseAlert = UIAlertController(title: "Done", message: "Do you want to save the Git credential password/passphrase?", preferredStyle: UIAlertControllerStyle.alert)
diff --git a/passKit/Helpers/AppError.swift b/passKit/Helpers/AppError.swift
index 2a96877..c185ea8 100644
--- a/passKit/Helpers/AppError.swift
+++ b/passKit/Helpers/AppError.swift
@@ -10,7 +10,8 @@ import Foundation
public enum AppError: Error {
case RepositoryNotSetError
- case RepositoryRemoteMasterNotFoundError
+ case RepositoryRemoteBranchNotFoundError(_: String)
+ case RepositoryBranchNotFound(_: String)
case KeyImportError
case PasswordDuplicatedError
case GitResetError
@@ -25,8 +26,10 @@ extension AppError: LocalizedError {
switch self {
case .RepositoryNotSetError:
return "Git repository is not set."
- case .RepositoryRemoteMasterNotFoundError:
- return "Cannot find remote branch origin/master."
+ case let .RepositoryRemoteBranchNotFoundError(remoteBranchName):
+ return "Cannot find remote branch 'origin/\(remoteBranchName)'."
+ case let .RepositoryBranchNotFound(branchName):
+ return "Branch with name '\(branchName)' not found in repository."
case .KeyImportError:
return "Cannot import the key."
case .PasswordDuplicatedError:
diff --git a/passKit/Helpers/DefaultsKeys.swift b/passKit/Helpers/DefaultsKeys.swift
index 8f5c47e..e5b08f5 100644
--- a/passKit/Helpers/DefaultsKeys.swift
+++ b/passKit/Helpers/DefaultsKeys.swift
@@ -22,6 +22,7 @@ public extension DefaultsKeys {
static let gitURL = DefaultsKey("gitURL")
static let gitAuthenticationMethod = DefaultsKey("gitAuthenticationMethod")
static let gitUsername = DefaultsKey("gitUsername")
+ static let gitBranchName = DefaultsKey("gitBranchName")
static let gitSSHPrivateKeyURL = DefaultsKey("gitSSHPrivateKeyURL")
static let gitSSHKeySource = DefaultsKey("gitSSHKeySource")
static let gitSSHPrivateKeyArmor = DefaultsKey("gitSSHPrivateKeyArmor")
diff --git a/passKit/Models/PasswordStore.swift b/passKit/Models/PasswordStore.swift
index 7035303..5f9e381 100644
--- a/passKit/Models/PasswordStore.swift
+++ b/passKit/Models/PasswordStore.swift
@@ -299,6 +299,7 @@ public class PasswordStore {
public func cloneRepository(remoteRepoURL: URL,
credential: GitCredential,
+ branchName: String,
requestGitPassword: @escaping (GitCredential.Credential, String?) -> String?,
transferProgressBlock: @escaping (UnsafePointer, UnsafeMutablePointer) -> Void,
checkoutProgressBlock: @escaping (String?, UInt, UInt) -> Void) throws {
@@ -312,6 +313,7 @@ public class PasswordStore {
storeRepository = try GTRepository.clone(from: remoteRepoURL, toWorkingDirectory: tempStoreURL, options: options, transferProgressBlock:transferProgressBlock)
try fm.moveItem(at: tempStoreURL, to: storeURL)
storeRepository = try GTRepository(url: storeURL)
+ try checkoutAndChangeBranch(withName: branchName)
} catch {
credential.delete()
DispatchQueue.main.async {
@@ -328,6 +330,27 @@ public class PasswordStore {
}
}
+ private func checkoutAndChangeBranch(withName localBranchName: String) throws {
+ if (localBranchName == "master") {
+ return
+ }
+ guard let storeRepository = storeRepository else {
+ throw AppError.RepositoryNotSetError
+ }
+ let remoteBranchName = "origin/\(localBranchName)"
+ guard let remoteBranch = try? storeRepository.lookUpBranch(withName: remoteBranchName, type: .remote, success: nil) else {
+ throw AppError.RepositoryRemoteBranchNotFoundError(remoteBranchName)
+ }
+ guard let remoteBranchOid = remoteBranch.oid else {
+ throw AppError.RepositoryRemoteBranchNotFoundError(remoteBranchName)
+ }
+ let localBranch = try storeRepository.createBranchNamed(localBranchName, from: remoteBranchOid, message: nil)
+ try localBranch.updateTrackingBranch(remoteBranch)
+ let checkoutOptions = GTCheckoutOptions.init(strategy: .force)
+ try storeRepository.checkoutReference(localBranch.reference, options: checkoutOptions)
+ try storeRepository.moveHEAD(to: localBranch.reference)
+ }
+
public func pullRepository(credential: GitCredential, requestGitPassword: @escaping (GitCredential.Credential, String?) -> String?, transferProgressBlock: @escaping (UnsafePointer, UnsafeMutablePointer) -> Void) throws {
guard let storeRepository = storeRepository else {
throw AppError.RepositoryNotSetError
@@ -567,9 +590,9 @@ public class PasswordStore {
do {
let credentialProvider = try credential.credentialProvider(requestGitPassword: requestGitPassword)
let options = [GTRepositoryRemoteOptionsCredentialProvider: credentialProvider]
- if let masterBranch = try getLocalBranch(withName: "master") {
+ if let branch = try getLocalBranch(withName: SharedDefaults[.gitBranchName]!) {
let remote = try GTRemote(name: "origin", in: storeRepository)
- try storeRepository.push(masterBranch, to: remote, withOptions: options, progress: transferProgressBlock)
+ try storeRepository.push(branch, to: remote, withOptions: options, progress: transferProgressBlock)
}
} catch {
throw(error)
@@ -790,19 +813,18 @@ public class PasswordStore {
guard let storeRepository = storeRepository else {
throw AppError.RepositoryNotSetError
}
- // get the remote origin/master branch
- guard let index = try storeRepository.remoteBranches().index(where: { $0.shortName == "master" }) else {
- throw AppError.RepositoryRemoteMasterNotFoundError
+ // get the remote branch
+ let remoteBranchName = SharedDefaults[.gitBranchName]!
+ guard let remoteBranch = try storeRepository.remoteBranches().first(where: { $0.shortName == remoteBranchName }) else {
+ throw AppError.RepositoryRemoteBranchNotFoundError(remoteBranchName)
}
- let remoteMasterBranch = try storeRepository.remoteBranches()[index]
-
// check oid before calling localCommitsRelative
- guard remoteMasterBranch.oid != nil else {
- throw AppError.RepositoryRemoteMasterNotFoundError
+ guard remoteBranch.oid != nil else {
+ throw AppError.RepositoryRemoteBranchNotFoundError(remoteBranchName)
}
// get a list of local commits
- return try storeRepository.localCommitsRelative(toRemoteBranch: remoteMasterBranch)
+ return try storeRepository.localCommitsRelative(toRemoteBranch: remoteBranch)
}