Another Git day today... this time I did the "Git Real" course on Code School (yesterday's article - "Two birds; one... stone" - was around their freebie intro course "tryGit").
I found today's course a bit superficial... TBH I think I learned more in the tryGit one than I did this one. I guess the things to learn about Git are more conceptual than "what one types at the keyboard", so the exercises in a Code School sort of environment will be a bit basic? It seemed more a test of whether I was paying attention to the videos, than whether I actually absorbed anything.
That said, it's given me another list of things to look at in more depth, which I'll do here. And I do think I have improved my understanding as to the mindset Git operates with, in contrast to how SVN (which I have a dozen years experience with) works. So this is valuable. OK, so I have this list of git commands to investigate further. And I'll document 'em here.
git config
One good thing about Git... what the commands do are pretty self explanatory. git config
manages your Git config (read that one a coupla times if it doesn't sink in the first time. I know it's complex stuff ;-). here's my config in that repo I was looking at y/day:
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git config -l
core.symlinks=false
core.autocrlf=true
color.diff=auto
color.status=auto
color.branch=auto
color.interactive=true
pack.packsizelimit=2g
help.format=html
http.sslcainfo=/bin/curl-ca-bundle.crt
sendemail.smtpserver=/bin/msmtp.exe
diff.astextplain.textconv=astextplain
rebase.autosquash=true
user.name=Adam Cameron
user.email=dac.cfml@gmail.com
core.autocrlf=true
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.symlinks=false
core.ignorecase=true
core.hidedotfiles=dotGitOnly
remote.origin.url=git@github.com:daccfml/git-tutorials.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$
$ git config -l
core.symlinks=false
core.autocrlf=true
color.diff=auto
color.status=auto
color.branch=auto
color.interactive=true
pack.packsizelimit=2g
help.format=html
http.sslcainfo=/bin/curl-ca-bundle.crt
sendemail.smtpserver=/bin/msmtp.exe
diff.astextplain.textconv=astextplain
rebase.autosquash=true
user.name=Adam Cameron
user.email=dac.cfml@gmail.com
core.autocrlf=true
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.symlinks=false
core.ignorecase=true
core.hidedotfiles=dotGitOnly
remote.origin.url=git@github.com:daccfml/git-tutorials.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$
I dunno what much of that stuff means either, if I'm honest.
That config shows the config settings accumulated from three different files:
[git install dir]/etc/gitconfig
(C:\apps\git\etc\gitconfig
for me)[user dir]/.gitconfig
(C:\users\adam.cameron\.gitconfig
)[repo dir]/.git/config
(C:\temp\octobox\.git\config
)
[core]
symlinks = false
autocrlf = true
[color]
diff = auto
status = auto
branch = auto
interactive = true
[pack]
packSizeLimit = 2g
[help]
format = html
[http]
sslCAinfo = /bin/curl-ca-bundle.crt
[sendemail]
smtpserver = /bin/msmtp.exe
[diff "astextplain"]
textconv = astextplain
[rebase]
autosquash = true
[user]
name = Adam Cameron
email = dac.cfml@gmail.com
[core]
autocrlf = true
[core]
repositoryformatversion = 0
filemode = false
bare = false
logallrefupdates = true
symlinks = false
ignorecase = true
hideDotFiles = dotGitOnly
[remote "origin"]
url = git@github.com:daccfml/git-tutorials.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[user]
The settings in those files are loaded in turn, and the most localised of any same-named settings are used (so a
local
setting overrides a global
setting, which itself overrides a system
-wide one). And all three can be set at once:
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git config --system user.email daccfml@gmail.com
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git config --global user.email dac.cfml+git@gmail.com
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git config user.email dac.cfml+octobox@gmail.com
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git config -l
core.symlinks=false
core.autocrlf=true
color.diff=auto
color.status=auto
color.branch=auto
color.interactive=true
pack.packsizelimit=2g
help.format=html
http.sslcainfo=/bin/curl-ca-bundle.crt
sendemail.smtpserver=/bin/msmtp.exe
diff.astextplain.textconv=astextplain
rebase.autosquash=true
user.email=daccfml@gmail.com
user.name=Adam Cameron
user.email=dac.cfml+git@gmail.com
core.autocrlf=true
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.symlinks=false
core.ignorecase=true
core.hidedotfiles=dotGitOnly
remote.origin.url=git@github.com:daccfml/git-tutorials.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
user.email=dac.cfml+octobox@gmail.com
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$
$ git config --system user.email daccfml@gmail.com
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git config --global user.email dac.cfml+git@gmail.com
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git config user.email dac.cfml+octobox@gmail.com
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git config -l
core.symlinks=false
core.autocrlf=true
color.diff=auto
color.status=auto
color.branch=auto
color.interactive=true
pack.packsizelimit=2g
help.format=html
http.sslcainfo=/bin/curl-ca-bundle.crt
sendemail.smtpserver=/bin/msmtp.exe
diff.astextplain.textconv=astextplain
rebase.autosquash=true
user.email=daccfml@gmail.com
user.name=Adam Cameron
user.email=dac.cfml+git@gmail.com
core.autocrlf=true
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.symlinks=false
core.ignorecase=true
core.hidedotfiles=dotGitOnly
remote.origin.url=git@github.com:daccfml/git-tutorials.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
user.email=dac.cfml+octobox@gmail.com
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$
Here I've set the
user.email
setting in each of system
, global
and local
(I didn't specify "local
", as that's what the default is). And they're shown individually in the config listing. They've also updated those files I mentioned before too. Here's the system-wide one (C:\apps\git\etc\gitconfig
):[core]
symlinks = false
autocrlf = true
[color]
diff = auto
status = auto
branch = auto
interactive = true
[pack]
packSizeLimit = 2g
[help]
format = html
[http]
sslCAinfo = /bin/curl-ca-bundle.crt
[sendemail]
smtpserver = /bin/msmtp.exe
[diff "astextplain"]
textconv = astextplain
[rebase]
autosquash = true
[user]
email = daccfml@gmail.com
If I pop into my scratch repo and list the config there, I see the system and global setting, but not the one local to the octobox repo:
adam.cameron@ACBIGLAPTOP /c/webroots/shared/git (master)
$ git config -l
core.symlinks=false
core.autocrlf=true
color.diff=auto
color.status=auto
color.branch=auto
color.interactive=true
pack.packsizelimit=2g
help.format=html
http.sslcainfo=/bin/curl-ca-bundle.crt
sendemail.smtpserver=/bin/msmtp.exe
diff.astextplain.textconv=astextplain
rebase.autosquash=true
user.email=daccfml@gmail.com
user.name=Adam Cameron
user.email=dac.cfml+git@gmail.com
core.autocrlf=true
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.symlinks=false
core.ignorecase=true
core.hidedotfiles=dotGitOnly
remote.origin.url=git@github.com:daccfml/scratch.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
adam.cameron@ACBIGLAPTOP /c/webroots/shared/git (master)
$
$ git config -l
core.symlinks=false
core.autocrlf=true
color.diff=auto
color.status=auto
color.branch=auto
color.interactive=true
pack.packsizelimit=2g
help.format=html
http.sslcainfo=/bin/curl-ca-bundle.crt
sendemail.smtpserver=/bin/msmtp.exe
diff.astextplain.textconv=astextplain
rebase.autosquash=true
user.email=daccfml@gmail.com
user.name=Adam Cameron
user.email=dac.cfml+git@gmail.com
core.autocrlf=true
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.symlinks=false
core.ignorecase=true
core.hidedotfiles=dotGitOnly
remote.origin.url=git@github.com:daccfml/scratch.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
adam.cameron@ACBIGLAPTOP /c/webroots/shared/git (master)
$
I can also just get a local-specific config listing:
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git config -l --local
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.symlinks=false
core.ignorecase=true
core.hidedotfiles=dotGitOnly
remote.origin.url=git@github.com:daccfml/git-tutorials.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
user.email=dac.cfml+octobox@gmail.com
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$
$ git config -l --local
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.symlinks=false
core.ignorecase=true
core.hidedotfiles=dotGitOnly
remote.origin.url=git@github.com:daccfml/git-tutorials.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
user.email=dac.cfml+octobox@gmail.com
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$
There's also
--global
and --system
options on the listing too (I'll spare you the output: you get the idea)To remove a config setting, one uses the
--unset
option:
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git config -l --local
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.symlinks=false
core.ignorecase=true
core.hidedotfiles=dotGitOnly
remote.origin.url=git@github.com:daccfml/git-tutorials.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
user.email=dac.cfml+octobox@gmail.com
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git config --unset user.email
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git config -l --local
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.symlinks=false
core.ignorecase=true
core.hidedotfiles=dotGitOnly
remote.origin.url=git@github.com:daccfml/git-tutorials.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$
$ git config -l --local
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.symlinks=false
core.ignorecase=true
core.hidedotfiles=dotGitOnly
remote.origin.url=git@github.com:daccfml/git-tutorials.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
user.email=dac.cfml+octobox@gmail.com
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git config --unset user.email
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git config -l --local
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.symlinks=false
core.ignorecase=true
core.hidedotfiles=dotGitOnly
remote.origin.url=git@github.com:daccfml/git-tutorials.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$
More on git add
/ adding when committing
(this article is going to just be a brain dump of the stuff I'm gleaning from the tutorial, so it might be a great raft of stuff like above, or just some bullet points)Yesterday I covered the subtle difference between these two statements:
git add *.txt
git add '*.txt'
The former only adds files from the current directory; the latter recursively adds files matching the pattern in subdirectories too.
One can also list multiple files in a git add statement:
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
rua.txt
tahi.txt
nothing added to commit but untracked files present (use "git add" to track)
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git add tahi.txt rua.txt
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: rua.txt
new file: tahi.txt
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
rua.txt
tahi.txt
nothing added to commit but untracked files present (use "git add" to track)
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git add tahi.txt rua.txt
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: rua.txt
new file: tahi.txt
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$
Here I've added
tahi.txt
and rua.txt
in one statement. One can also add all files
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git statusOn branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: rua.txt
new file: tahi.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
more/
toru.txt
wha.txt
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git add --all
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git statusOn branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: more/ono.txt
new file: more/rima.txt
new file: rua.txt
new file: tahi.txt
new file: toru.txt
new file: wha.txt
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$
$ git statusOn branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: rua.txt
new file: tahi.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
more/
toru.txt
wha.txt
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git add --all
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git statusOn branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: more/ono.txt
new file: more/rima.txt
new file: rua.txt
new file: tahi.txt
new file: toru.txt
new file: wha.txt
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$
One can also do
git add .
to effect the same results.One of the best things I learned today is that one can add & commit in one fell swoop with the
-a
switch on a git commit call:
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
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: rua.txt
modified: tahi.txt
modified: toru.txt
modified: wha.txt
no changes added to commit (use "git add" and/or "git commit -a")
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git commit -am "update files 1-4"
[master fbaddd8] update files 1-4
4 files changed, 4 insertions(+), 4 deletions(-)
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
(use "git push" to publish your local commits)
nothing to commit, working directory clean
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$
$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
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: rua.txt
modified: tahi.txt
modified: toru.txt
modified: wha.txt
no changes added to commit (use "git add" and/or "git commit -a")
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git commit -am "update files 1-4"
[master fbaddd8] update files 1-4
4 files changed, 4 insertions(+), 4 deletions(-)
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
(use "git push" to publish your local commits)
nothing to commit, working directory clean
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$
Notice that it's not reporting "changes to be committed" like the previous example above did, this time it's saying everything is committed, ready to push up the remote repository.
Note two things here:
- this "add" operation does not add untracked files (like
git add
might), it only adds untracked changes to previously tracked files. - I used
-am
here. That's the equivalent of-a -m
. So the option is not "am
", it's two options concatentated together. I just think that looks cleaner.
Different degrees of git reset
ting
soft
We had the briefest of looks at this yesterday, but I learned some more handy options today.Firstly we can roll-back to the state files were in before an earlier commit:
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
(use "git push" to publish your local commits)
nothing to commit, working directory clean
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git reset --soft HEAD^
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: rua.txt
modified: tahi.txt
modified: toru.txt
modified: wha.txt
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$
$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
(use "git push" to publish your local commits)
nothing to commit, working directory clean
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git reset --soft HEAD^
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: rua.txt
modified: tahi.txt
modified: toru.txt
modified: wha.txt
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$
There's two things to to note from that git reset call above. Firstly the "
soft
" setting means "just uncommit" (but otherwise don't change the files themselves). Secondly the "^
" notation on the HEAD
. Remember the HEAD
is just the most up-to-date revision of the current branch in the repository. Suffixing this with "^
" means "previous to ~": so we're resetting to the state the repo was in at the commit previous to the current HEAD
. And we see that that was the state in which those four files had been updated, but not committed. Cool.One can also add multiple "
^
" signs to skip back multiple commits, as demonstrated in this long-winded example (below). Here I am updating tahi.txt
and rua.txt
. This statement just appends " updated
" to the file's contents:echo " updated" >> tahi.txt
(that's just BASH, it's nothing to do with Git).
And then committing them. Then doing the same with
toru.txt
and wha.txt
.I then roll back one commit (
^
) and check the status: only toru.txt
and wha.txt
to commit again. Then I roll back to two commits previous to the HEAD
(^^
), and now see that tahi.txt
and rua.txt
also now need committing:
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ echo " updated" >> tahi.txt
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ echo " updated" >> rua.txt
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git commit -am "updated 1+2"
[master 6308a52] updated 1+2
2 files changed, 2 insertions(+), 2 deletions(-)
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ echo " updated" >> toru.txt
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ echo " updated" >> wha.txt
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git commit -am "updated 3+4"
[master warning bd6b933] updated 3+4
2 files changed, 2 insertions(+), 2 deletions(-)
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
(use "git push" to publish your local commits)
nothing to commit, working directory clean
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git reset --soft head^
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: toru.txt
modified: wha.txt
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git reset --soft head^^
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git status
On branch master
Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
(use "git pull" to update your local branch)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: rua.txt
modified: tahi.txt
modified: toru.txt
modified: wha.txt
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$
$ echo " updated" >> tahi.txt
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ echo " updated" >> rua.txt
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git commit -am "updated 1+2"
[master 6308a52] updated 1+2
2 files changed, 2 insertions(+), 2 deletions(-)
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ echo " updated" >> toru.txt
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ echo " updated" >> wha.txt
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git commit -am "updated 3+4"
[master warning bd6b933] updated 3+4
2 files changed, 2 insertions(+), 2 deletions(-)
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
(use "git push" to publish your local commits)
nothing to commit, working directory clean
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git reset --soft head^
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: toru.txt
modified: wha.txt
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git reset --soft head^^
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git status
On branch master
Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
(use "git pull" to update your local branch)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: rua.txt
modified: tahi.txt
modified: toru.txt
modified: wha.txt
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$
hard
Obviously if there's asoft
option, there's also the hard
way. a hard reset not only undoes the git activity, it also undoes changes in the actual files too. Here's an example. Before the output below, I reverted the reset
from the example above, and made sure my working directory was clean and matched the Github repository. So there were no changes anywhere.I then went through and repeated the exercise of updating and committing
tahi.txt
and rua.txt
; then did the same with toru.txt
and wha.txt
. And pushed that up to Github. So, again, everything was married up both locally and remotely.And here's the screen cap of an exercise showing a hard reset:
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
So this demonstrates we're all committed and up to date ("nothing up my sleeves", basically)
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git log -n 3 --reverse --format="%cr %s"
12 minutes ago reset 1-4
11 minutes ago 1+2 updated before HARD reset test
10 minutes ago 3+4 updated before HARD reset test
$ git log -n 3 --reverse --format="%cr %s"
12 minutes ago reset 1-4
11 minutes ago 1+2 updated before HARD reset test
10 minutes ago 3+4 updated before HARD reset test
This shows the commit messages of the last three commits. The latter two being the commits I did for this exercise, and the former one being just whatever I committed previous to that (as a baseline).
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ cat tahi.txt
one updated
$ cat tahi.txt
one updated
The
cat
(BASH) command just outputs the contents of the specified file. Note that tahi.txt
contains the "updated" value here.
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git reset --hard HEAD^^
HEAD is now at 8e064cd reset 1-4
$ git reset --hard HEAD^^
HEAD is now at 8e064cd reset 1-4
So I do the hard reset. Note that the
HEAD
is now back past the two test commits, and positioned at the previous one (the first one listed above).
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ cat tahi.txt
one
$ cat tahi.txt
one
And the contents of
tahi.txt
have been rolled back too. This is the difference between a hard
and soft
reset. A soft reset only resets Git activity, a hard reset rolls back the file system activity too.
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git status
On branch master
Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
nothing to commit, working directory clean
$ git status
On branch master
Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
nothing to commit, working directory clean
This shows that nothing is lying around to commit (so all the changes to the files are gone), and the local branch is two commits behind the remote one.
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git pull
Updating 8e064cd..a1beae4
Fast-forward
rua.txt | 2 +-
tahi.txt | 2 +-
toru.txt | 2 +-
wha.txt | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ cat tahi.txt
one updated
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$
$ git pull
Updating 8e064cd..a1beae4
Fast-forward
rua.txt | 2 +-
tahi.txt | 2 +-
toru.txt | 2 +-
wha.txt | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ cat tahi.txt
one updated
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$
Doing a pull restores the previously committed files (and their contents); showing the reset only impacts the local repository, not the remote one.
Hopefully that makes sense? It didn't to me during the course, but once I started playing around with it, it cleared itself up.
Editing a commit
This is cool. We can update a previous commit by amending it. Here's an example:
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
Just like before, we're starting from a clean slate.
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git diff
diff --git a/tahi.txt b/tahi.txt
index 6b1c933..40090cc 100644
--- a/tahi.txt
+++ b/tahi.txt
@@ -1 +1 @@
-one updated
+one change for initial commit
$ git diff
diff --git a/tahi.txt b/tahi.txt
index 6b1c933..40090cc 100644
--- a/tahi.txt
+++ b/tahi.txt
@@ -1 +1 @@
-one updated
+one change for initial commit
Behind the scenes (I forgot to use
cat
this time) I have changed the contents of tahi.txt
from "one updated
" to "one change for initial commit
".
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git commit -am "initial commit"
[master acbc224] initial commit
1 file changed, 1 insertion(+), 1 deletion(-)
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git log -n 2 --reverse --format="%cr %s"
47 minutes ago 3+4 updated before HARD reset test
60 seconds ago initial commit
$ git commit -am "initial commit"
[master acbc224] initial commit
1 file changed, 1 insertion(+), 1 deletion(-)
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git log -n 2 --reverse --format="%cr %s"
47 minutes ago 3+4 updated before HARD reset test
60 seconds ago initial commit
I commit that change, and list the log of the two most recent commits: the one I've just done, and the previous one.
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git diff
diff --git a/tahi.txt b/tahi.txt
index 40090cc..979d896 100644
--- a/tahi.txt
+++ b/tahi.txt
@@ -1 +1 @@
-one change for initial commit
+one change for initial commit (and a second update to amend that commit with)
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git diff
diff --git a/tahi.txt b/tahi.txt
index 40090cc..979d896 100644
--- a/tahi.txt
+++ b/tahi.txt
@@ -1 +1 @@
-one change for initial commit
+one change for initial commit (and a second update to amend that commit with)
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
Again, I've updated
tahi.txt
behind the scenes.
$ git commit --amend -am "This comment should replace the previous commit comment"
[master 8a2f422] This comment should replace the previous commit comment
1 file changed, 1 insertion(+), 1 deletion(-)
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working directory clean
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git log -n 2 --reverse --format="%cr %s"
48 minutes ago 3+4 updated before HARD reset test
25 seconds ago This comment should replace the previous commit comment
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$
[master 8a2f422] This comment should replace the previous commit comment
1 file changed, 1 insertion(+), 1 deletion(-)
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working directory clean
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$ git log -n 2 --reverse --format="%cr %s"
48 minutes ago 3+4 updated before HARD reset test
25 seconds ago This comment should replace the previous commit comment
adam.cameron@ACBIGLAPTOP /c/temp/octobox (master)
$
And I use
amend
to amend the previous commit, and use a new message. This is borne out by looking at the log: the previous message has gone, as indeed has the entire commit record, being replaced with the updated one.OK, that's enough for the time being. My brain is full, my fingers are tired, and I am hungry... and it's a slow cook tonight so if I start now, dinner ain't gonna be ready for another coupla hours anyhow.
Anyhow, that's a chunk of stuff for you to read through. Interestingly this lot only overs the first 1.5 videos on this course, out of seven. I've got a long way to go.
Righto.
--
Adam