As an iOS developer I started working with Xcode's Git integration back in the years of iOS 13/14. During that time I've had to face lots of problems with it mostly when merging big developments, straight to the point where the other day I had to redo a complete development on a new branch because the merge wouldn't work at all.
To avoid more headaches with Xcode's Git integration I've gone back to basics and have begun to use the Terminal for Git. Yes, using the Terminal is not as visual as Xcode's UI, but I've found it to be way more reliable. Here are my recommendations for using Git with Terminal:
First is thing would be to install Oh My Zsh, which is an open source, community-driven framework that manages your Zsh configuration. It makes Zsh more powerful and friendly and it shows you your current Git branch in the prompt, along with helpful color cues for staged, unstaged, and uncommitted changes. To install just type this:
Then I'd suggest trying to remember the following shortcut for clearing the whole Terminal output for when it gets too messy:
Now here comes all the commands I've found useful to substitute the use of Xcode's Git integration:
CLONE
Clones a remote repository and automatically sets it as the remote named origin.
• Clone a remote repository
• Clone a repository into a specific folder
• Clone a specific branch
FETCH
Updates local references to remote branches but does not merge changes automatically.
• Fetch updates from origin
• Fetch a specific branch from origin
• Fetch all remotes
BRANCH
• List local branches
• List all branches (remote + local)
• Create new branch
• Copy an existing local branch into a new local branch (without moving HEAD)
• Delete local branch
• Switch to an existing branch
• Create a new branch from the current one and switch to it
PULL
• Pull current branch from origin
• Pull an existing branch from origin
PUSH
• Push your current branch to origin
• Push existing branch to origin
• First time push (set upstream)
COMMIT
• Commit staged changes with a message
• Amend last commit
STATUS
• Check current local branch status
OPEN
• Open directory in external editor (e.g., Sublime Text)
• Open file in external editor (e.g., Sublime Text)
• Open file in merge tool
CHECKOUT
• Keep only “theirs” or “ours” changes
• Stage a specific file
• Stage all files in current directory
• Stage all changes in the repository (including deletions)
REMOVE
• Mark a file as removed and stage the deletion
DIFF
• See differences for a conflicted file
MERGE
• Abort merge
• Continue merge when conflicts are resolved
• Save tracked changes and clean working directory
• Save tracked changes with a message
• Save tracked + untracked files
• List all stashes
• Apply specific stash
• Apply last stash and remove it from stash list
• Delete specific stash
• Delete all stashes
RESTORE
For restoring files or undoing staged changes without changing branch history so it only affects your working directory or staging area.
• Restore all modified files in directory
• Restore a specific file to discard all local changes in it
• Unstage all staged changes
• Unstage a specific file (undo git add)
RESET
For changing the branch history by moving the branch pointer to a previous commit. It can also change staged changes and working directory depending on the options.
• Reset staged changes
• Reset branch to a previous commit
To avoid more headaches with Xcode's Git integration I've gone back to basics and have begun to use the Terminal for Git. Yes, using the Terminal is not as visual as Xcode's UI, but I've found it to be way more reliable. Here are my recommendations for using Git with Terminal:
First is thing would be to install Oh My Zsh, which is an open source, community-driven framework that manages your Zsh configuration. It makes Zsh more powerful and friendly and it shows you your current Git branch in the prompt, along with helpful color cues for staged, unstaged, and uncommitted changes. To install just type this:
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
Then I'd suggest trying to remember the following shortcut for clearing the whole Terminal output for when it gets too messy:
⌘ + ⌥ + L
Now here comes all the commands I've found useful to substitute the use of Xcode's Git integration:
CLONE
Clones a remote repository and automatically sets it as the remote named origin.
• Clone a remote repository
Downloads the entire repository from the remote server and creates a local copy on your machine.git clone repository_url
• Clone a repository into a specific folder
Downloads the repository and places it into a folder with the specified name.git clone repository_url folder_name
• Clone a specific branch
Clones the repository and checks out the specified branch instead of the default one.git clone --branch branch_name repository_url
FETCH
Updates local references to remote branches but does not merge changes automatically.
• Fetch updates from origin
Downloads the latest changes from the remote repository without merging them into your current branch.git fetch
• Fetch a specific branch from origin
Downloads updates for the specified branch without modifying your local branch.git fetch origin branch_name
• Fetch all remotes
Downloads updates from all remote repositories.git fetch --all
BRANCH
• List local branches
Shows all branches on your machine. The * indicates the branch you’re currently on.git branch
• List all branches (remote + local)
Shows both local branches and branches on the remote repository.git branch -a
• Create new branch
This makes a new branch, but you stay on your current branch.git branch branch_name
• Copy an existing local branch into a new local branch (without moving HEAD)
Creates a new branch with the same content as branch_name without switching to it while HEAD remains on your current branch.git branch -c branch_name new_branch_name
• Delete local branch
Deletes the branch. Git will prevent deletion if the branch has unmerged changes.SWITCHgit branch -d branch_name
• Switch to an existing branch
Moves you to the branch you specify.git switch branch_name
• Create a new branch from the current one and switch to it
Makes a new branch based on your current branch and switches to it immediately.git switch -c branch_name
PULL
• Pull current branch from origin
Fetches and merges changes from the remote branch you’re tracking.git pull
• Pull an existing branch from origin
Fetches and merges updates from branch_name on the remote repository.git pull origin branch_name
PUSH
• Push your current branch to origin
Sends your commits to the remote branch you’re tracking.git push
• Push existing branch to origin
Uploads your branch to the remote repository.git push origin branch_name
• First time push (set upstream)
Sets the remote branch as the default upstream for future pushes and pulls.git push -u origin branch_name
COMMIT
• Commit staged changes with a message
Saves your staged changes to the repository with a description.git commit -m "message"
• Amend last commit
Changes the most recent commit (e.g., to fix the message or add missing files).git commit --amend
STATUS
• Check current local branch status
Shows staged changes, unstaged changes, and untracked files.git status
OPEN
• Open directory in external editor (e.g., Sublime Text)
open -a “Sublime Text” .
• Open file in external editor (e.g., Sublime Text)
open -a “Sublime Text” "File Name"
• Open file in merge tool
git mergetool "File Name"
CHECKOUT
• Keep only “theirs” or “ours” changes
Use when resolving merge conflicts and choosing one version.ADDgit checkout [--theirs || --ours] "File Name"
• Stage a specific file
git add "File Name"
• Stage all files in current directory
git add .
• Stage all changes in the repository (including deletions)
git add -A
REMOVE
• Mark a file as removed and stage the deletion
git rm "File Name"
DIFF
• See differences for a conflicted file
Shows what changed before committing.git diff -- "File Name"
MERGE
• Abort merge
Cancels a merge in progress.git merge --abort
• Continue merge when conflicts are resolved
Completes the merge once conflicts are fixed.STASHgit merge --continue
• Save tracked changes and clean working directory
git stash
• Save tracked changes with a message
git stash push -m "message"
• Save tracked + untracked files
git stash push -u
• List all stashes
git stash list
• Apply specific stash
git stash apply stash@{n}
• Apply last stash and remove it from stash list
git stash pop
• Delete specific stash
git stash drop stash@{n}
• Delete all stashes
git stash clear
RESTORE
For restoring files or undoing staged changes without changing branch history so it only affects your working directory or staging area.
• Restore all modified files in directory
Discards all local changes in all your files from the working directory without touching commits.git restore .
• Restore a specific file to discard all local changes in it
Discards all local changes in the specified file from the working directory. Handy if you want to undo edits.git restore "File Name"
• Unstage all staged changes
Moves all files out of staging keeping the edits in the working directory.git restore --staged .
• Unstage a specific file (undo git add)
Moves the specified file out of staging keeping the file edits in the working directory. Handy if you added the wrong file to staging by mistake.git restore --staged "File Name"
RESET
For changing the branch history by moving the branch pointer to a previous commit. It can also change staged changes and working directory depending on the options.
• Reset staged changes
Unstages all staged files but keeps the changes in the working directory.git reset
• Reset branch to a previous commit
Resets the current branch to the specified commit clearing the staging area and discarding any working directory edits. Warning: This rewrites branch history and permanently removes uncommitted work.git reset --hard commit_hash