Git flow for pros - mhulse/mhulse.github.io GitHub Wiki
Git check out tag, then check out temp branch (git branch tmp
), git cherry-pick hash onto this temp local branch, resolve conflicts/make any changes and commit them locally, then tag tmp branch and push tag. This tag can then be used by ENG to work from until they can update to latest master. You can push branch up if you like, to keep it somewhere safe, or just keep it around locally until ENG has moved on and release is good to go.
Useful if you modify a file that you want to reset:
$ git co master -- public_html/assets/plugins/bootstrap-3.3.7/css/bootstrap.min.css
$ git grep "\$userCoaches" $(git rev-list --all)
The quote = regex, so escaping the dolla dolla sign is needed.
$ git co feature-branch
$ git fetch
$ git reset origin/feature-branch --hard
# or --soft to keep local tracked changes.
See: git pull after forced update
$ git branch | grep -v "master" | xargs git branch -D
$ git remote -v
$ git remote add upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git
$ git remote -v
$ git fetch upstream
$ git checkout master
$ git merge upstream/master
$ git checkout -B gh-pages master # Check out to gh-pages, starting from master
$ git checkout master # Move back to master
# Find last shared commit (e.g., if on master, go back to where branches converge):
$ git reset --hard f209b0e
$ git push -f
# If on Bitbucket, you will see “Commit deleted …” in the “Recent Activity” feed.
If you see something like:
$ git rebase -i master
error: could not apply 2146ce7... Working on it
First, fix the merge conflicts in your file(s) and then do this:
# You must edit all merge conflicts and then mark them as resolved using:
$ git add .
# Continue the rebase:
$ git rebase --continue
That’s it!
-
a
: Append text after the cursor [count] times. -
A
: Append text at the end of the line [count] times. -
i
: Insert text before the cursor [count] times. -
I
: Insert text before the first non-blank in the line [count] times. -
gI
: Insert text in column 1 [count] times. -
o
: Begin a new line below the cursor and insert text, repeat [count] times. -
O
: Begin a new line above the cursor and insert text, repeat [count] times.
$ git co master
$ git tag -a 'v0.3.0' -m 'Client-approved functionality.'
# List local tags:
$ git tag
v0.1.0
v0.2.0
v0.3.0
$ git push origin --tags
Checkout a specific tag:
$ git checkout tags/<tag_name>
# On local feature branch that's been deleted on remote repo:
$ git push -u origin feature-branch
# Above creates new branch.
$ git commit -am 'Message'
$ git push
$ git co master && git fetch && git pull
$ git co feature-branch
$ git rebase master
# Force it:
$ git push -f origin feature-branch
Alternatively, you could create a new branch off of the remotely-deleted feature-branch
and push, then rebase on master
and do a force push.
When git reset --hard
doesn’t seem to work … Delete it and then pull it fresh:
$ git branch -D feature-branch
$ git fetch origin feature-branch
$ git checkout -b feature-branch origin/feature-branch
Useful for repos hosted on GitHub that want to take advantage of GitHub pages:
# Create and clone your repo, then …
# Create the gh-pages branch:
$ git checkout -b gh-pages
# … and push:
$ git push -u origin gh-pages
Now, via the GitHub interface, click on your repo’s settings
link and choose gh-pages
as your default branch:
Back in the command line (this step is optional; only do this if you don’t want master
floating around):
# Delete local master branch:
$ git branch -D master
# Delete remote master branch:
$ git push origin --delete master
In recent Git 1.7.0+ you can do the following:
$ git checkout -b feature_branch_name # ... edit files, add and commit ... $ git push -u origin feature_branch_name # -u is short for --set-upstream
It's also worth noting that if you have an existing tracking branch already set on the branch you're pushing, and push.default is set to upstream, this will not do what you think it will do. It will try to push over the existing tracking branch. Use:
git push -u origin mynewfeature:mynewfeature
or dogit branch --unset-upstream
first.
Just do:
$ git reset --hard master
On feature branch (it is assumed that changes have already been made):
$ git add .
$ git commit -a
# Or, if not needing more than one line:
#$ git commit -am
In editor, type i
for insert mode.
First line should be title of commit … If using issue tracking system, like JIRA, put the issue number in parenthesis at the end.
Additional lines should be what was completed (with \n\n
separators).
To finish, type :wq
for “write and quit”.
Next, get latest commits from origin:
$ git checkout master
Check if there's anything new:
#$ git remote update && git status
# Faster to use:
$ git fetch
If so, run:
$ git fetch origin
$ git pull origin master
# This would work too:
#$ git fetch
#$ git pull
Go back to your feature branch:
$ git co feature-branch
And rebase:
$ git rebase -i master
When in VIM editor mode, use:
# Remove an entire line:
dd
# Remove first word and replace with another:
cw and hit s (squash) or f (fixup) or p (pick) to keep intact or r (reword)
# Exit insert mode:
esc
# Save:
:wq write quit
# Force quit, but this may save:
:q! force quit
# This will force an error to VIM and it will not save any changes:
:cq!
Use git log
(or git log oneline
) to see the clean/new commit message (previous commits to this feature branch should be gone/squashed into the latest commit at top).
Once that's complete, use:
$ git push -f origin feature-branch
Where the -f
means force
; we’re doing this due to the history change.
Never do a --force
on master
!
Next visit BitBucket (or GitHub) and use web interface; visit the branches section and switch to your feature-branch.
You should see your updated/squashed code; at this point, let the reviewer know you’ve updated things and they can take another look.
If your commit is approved, and once the code is merged, check out and update your master
branch:
$ git checkout master
$ git fetch origin
$ git pull origin master
$ git status
DONE! 👍
If you committed your work, made some more changes, and there are conflicts:
$ git reset --hard origin/feature-branch
$ git rebase -i master
$ git status
$ git add .
$ git status
# Continue the rebasing process:
$ git rebase --continue
# You should now see only one commit message at top:
$ git log
$ git push --force
If different files were touched, outside of the files you are touching in your feature branch, then you should not need to worry. BUT, better safe than sorry:
$ git co master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
$ git fetch
remote: Counting objects: 1, done.
remote: Total 1 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (1/1), done.
From bitbucket.org:ieq/parent-net-api
bf445e7..100a1ca master -> origin/master
$ git pull
Updating bf445e7..100a1ca
Fast-forward
client/js/controllers/childDetail.js | 49 +++++++++++++++++++++++++------------------------
client/js/controllers/modalInstance.js | 10 +++++++++-
client/views/modal.html | 1 +
3 files changed, 35 insertions(+), 25 deletions(-)
$ git co 66-header-
# Hit tab twice to see available feature branches:
66-header-css-layout-fix 66-header-fix
$ git co 66-header-css-layout-fix
Switched to branch '66-header-css-layout-fix'
$ git rebase master
First, rewinding head to replay your work on top of it...
Fast-forwarded 66-header-css-layout-fix to master.
If there were merge conflicts, rebase
would have made you fix them and then you would do a force push to your feature branch:
$ git push --force
$ git status
On branch FEATURE-BRANCH
Your branch is up-to-date with 'origin/FEATURE-BRANCH'.
nothing to commit, working directory clean
$ git fetch
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 5 (delta 3), reused 0 (delta 0)
Unpacking objects: 100% (5/5), done.
From bitbucket.org:ieq/repo
+ 59e4f8e...8cef25d FEATURE-BRANCH -> origin/FEATURE-BRANCH (forced update)
+ 0a9981a...c90c725 FEATURE-BRANCH -> origin/FEATURE-BRANCH (forced update)
$ git reset --hard origin/FEATURE-BRANCH
HEAD is now at 8cef25d COMMIT MESSAGE
The trick here, is the forced update
line; this is a signal that you can use reset --hard
.
In a team or open source environment, it’s preferable to have a workflow that involves feature branches, squash commits, and make pull requests.
If using a tracking system, name your branches with the issue number at front, like so:
99-my-feature-branch
This make it easy to checkout because you probably already know the issue number.
When creating commit messages, append the full issue number to the end of the message’s first line:
$ git commit -am 'This is my feature branch that fixes issue XXXXXX (PAR-99).
Depending on the issue tracking software, the issue number should then create a cross-link between the issue and the commit message (e.g. BitBucket and Jira).
If you ever get stuck on a feature branch during an update, run:
$ git reset --hard origin/feature-branch
If master
ever gets fucked, you can also do this:
$ git co master
$ git reset --hard origin/master
If all else fails, delete your local repo and re-clone! 😄
# Diff between current branch and master:
$ git diff master
# Diff between branch A and branch B (even if on branch C):
$ git diff branch-A branch-B
Cheat sheet for print:
# Adding features to a feature branch and rebasing
$ git add -a
$ git commit -m 'Commit message (issue number)' # Adds all tracked files to staging area and commits.
# OR:
# $ git commit -a # Commits all local changes in tracked files + editor.
# Vim: Type i for insert mode.
# First line should be title of commit …
# If using issue tracking system, like JIRA,
# put the issue number in parenthesis at the end.
# Additional lines should be a log of the work
# completed (with \n\n separators).
esc
:wq
$ git push # Optional.
# OR, if pushing for first time:
# $ git push --set-upstream origin feature-branch
$ git checkout master
$ git fetch && git pull
$ git checkout feature-branch
# Only do if multiple commits in history:
$ git rebase -i master
# Vim step 1:
cw and hit s (squash) or f (fixup) or p (pick) to keep intact or r (reword)
Note: keep first line as pick, and squash the rest.
esc
:wq (write and quit)
# Vim step 2:
dd (remove entire line)
a (append text after the cursor)
A (append text at the end of the line)
i (insert text before the cursor)
I (insert text before the first non-blank in the line)
gI (insert text in column 1)
o (begin a new line below the cursor and insert text)
O (begin a new line above the cursor and insert text)
esc
:wq (write and quit)
$ git log --oneline
$ git push -f origin feature-branch
# Never do a --force on master!
$ git checkout master
$ git fetch && git pull
$ git status