https://www.youtube.com/playlist?list=PLg7s6cbtAD15G8lNyoaYDuKZSKyJrgwB- https://www.youtube.com/watch?v=BKPjPMVB81g&index=20&list=PLg7s6cbtAD15G8lNyoaYDuKZSKyJrgwB-
A lot of developers have this workflow:
- make some changes
git add .
git commit -m "commit message"
- rinse and repeat
This workflow is error prone because the developer is not double checking the content of the commit they're making. git add .
will add all changes and all untracked files which means they're very likely to commit something they didn't really want to.
- make some changes
git add --patch
ORgit add -p
- review each change (or hunk) and only add the ones you want
git commit -m "commit message"
git add -p
- if you have remaining changes: go to step 2
- rinse and repeat
- make some changes
- make a
WIP
commitgit add . && git commit -m WIP
- goto step 1 until you're work is done
Note: I can get away with this because I always polish my commits before publishing them
You should always double check your commits and if need be polish them before you piblish them.
Note: by "Publish" I mean "make your commits available to others". This could be through pushing code to github or creating a pull-request, depending on your workflow
- ensure all your changes are committed
- reset back to your last good commit
git reset ???
- git a
git log
and copy the sha from the last good commit - if you don't have any good commits then reset back to the commit you branched off of
- now all of your work is on the disk waiting for you to check it in.
- look over all of your changes
git diff
and make a plan for how to group your changes into a few new commits
- try to group code by the kinds of changes it makes
- try to make each commit and atomic change
- hopefully each commit is theoretically revertible on its own
- consider if some commits belong on different branch AKA different pull-request
- it's okay if everything is one commit if it should be
- use
git add --patch
AKAgit add -p
to add changes for your first commit - keep adding your changes and making commits until your done
- if you find some code you should have added to a previous commit consider commiting it on its own later and using an interactive rebase
git rebase -i
tosquash
that commit into the one you should have added it to in the first place
- consider rebasing off master
git fetch origin && git rebase origin/master
- push it!
git push
git rebase
is a command that lest you replay your commits on top of other commits. We can use an interactive rebase git rebase -i
to modify our commits as they're replayed.
NOTE: by "replayed" I mean the commit is copied and applied to a different parent commit
An interactive rebase can be useful when you want to modify your commits in the following ways:
- add a change to a previous commit
- remove a change from a previous commit
- change a commit's commit message
- squash two commits together
- and a more :D
Lets say you have the following commits
f321d02 fixed bug in User model for real this time
df85c45 fixed bug in Post model
5679b24 added Comment model
e7c9c11 fixed bug in User model
c8a0b07 added Post model
02882f1 added User model
And what you want something like this:
fakesha2 added Comment model
fakesha1 added Post model
fakesha0 added User model
run git rebase -i $SHA~1
NOTE: $SHA should be the oldest commit you want to change
NOTE: ~1 means 1 commit before that
you should now be editing a file that looks something like this:
NOTE: notice our commits are listed in chronological order as apposed to 'git log` that shows commits in reverse-chronological order
pick 02882f1 added User model
pick c8a0b07 added Post model
pick e7c9c11 fixed bug in User model
pick 5679b24 added Comment model
pick df85c45 fixed bug in Post model
pick f321d02 fixed bug in User model for real this time
# Rebase 42ff192..02882f1 onto 42ff192 (65 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
if we make the following changes:
NOTE: the change in line order
pick 02882f1 added User model
fixup e7c9c11 fixed bug in User model
fixup f321d02 fixed bug in User model for real this time
pick c8a0b07 added Post model
fixup df85c45 fixed bug in Post model
pick 5679b24 added Comment model
# Rebase 42ff192..02882f1 onto 42ff192 (65 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
we will smash our commits together in a nice order
k. thanks. bye
In the most common case; Rebasing is the process by which you take the changes on your branch and move them onto the latest version master.
Here are a few videos explaining this
git log --oneline --graph --decorate
Staging is the process of adding your changes (or hunks) to the set of changes to be committed.
Note: a single change is called a hunk
You can view the status of your stage
When you run git status
, look for the following sections:
- Changes to be committed:
- Changes not staged for commit:
- Untracked files:
Here is an example of a status with all three cases:
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: existing-file-with-staged-changes.js
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: existing-file-with-unstaged-changes.js
Untracked files:
(use "git add <file>..." to include in what will be committed)
new-file.js
The simple way to do this is to use git add .
to add all changes to the stage
The best way to do this is to use git add --patch
OR git add -p
to pick and choose each change (or hunk) to add to the stage.
Note: a single change is called a hunk
The simple way to do this is to use git reset
The best way to do this is to use git reset --patch
OR git reset -p
The best way to do this is to use git add --patch
NOTE: read the Staging
section first.
You've used the git reset
command to remove changed from the stage. git reset
can also be used to change the SHA your branch is pointing to.