--- GIT TUTORIAL 2020-T ---
BEFORE YOU START:
Correct -> HEAD IS A POINTER TO YOUR CURRENT WORKSPACE LOCATION
That is HEAD will always point to the current branch you're working at.
MASTER is the current/main branch you'll be using for your project.
COMMITS are literal reference points for each commited changes you've made in your project.
File Update/Insertion/Removal (also, 'git add' and 'git rm') inside the MASTER Branch blocks
you from switching to other branches, until modifications are actually COMMITED - that's unless you're
in other branches.
VERY IMPORTANT: Take note that GIT uses a global buffer for implementing non-commited changes made to files called
INDEX, so when you move between branches/heads, you're taking the INDEX to whatever branches you are moving from/to,
until you 'git commit -m "Commit Name"' those changes, only then it turns these changes from global
to local modifications within that specific branch(aka.: where your current HEAD is point at).
Further More.: Index is a view of your working directory that is ready for commit.
It can be seen as a pre-commit state and is not as simple as a "list of files".
When you do git add, the file (with the change) is added to the index and the newer
changes will not be see until you add them too.
Note.: INDEX/Staging Area are the same thing!
Also, note that GIT is a DVCS - Distributed Version Controlling Software, that means each user has
it's own repo and it's own working area. VCS - Versionning Control Software only has 1 main repository,
and each user has it's own working area.
Git was made by Linus Trovalids
read more about Checking WORKING AREA, STAGING AREA, HEAD
VERY IMPORTANT: Staging Area are the files being staged by GIT!
The Working Area are the modifications being done to the Staging Area.
ex.: "git diff" will only show differences between commits for the Working Areas,
it'll however show no issues whether new_files are or not on the STAGING AREA.
THEREFORE The Staging area and Working Area are different things!
-----------------
BEFORE YOU CONTINUE:
On linux, you can get easy git documentation by typing:
$man git-log
^ this will allow you check manual pages on git log command, which would be the same as doing:
$git help log
There's also a good GIT GUI Client called git-tower: https://www.git-tower.com/
GIT EXERCISES: https://gitexercises.fracz.com/committer/ny4
----
EXERCISES SOLUTION:
Exercise 7: git rebase ***-bugfix
manual: https://www.benmarshall.me/git-rebase/
https://git-scm.com/docs/git-rebase
-----------------
Working Area, Staging Area, Head Area:
seus repositórios locais consistem em três "árvores" mantidas pelo git. a primeira delas é sua Working
Directory que contém os arquivos vigentes. a segunda Index que funciona como uma área temporária e
finalmente a HEAD que aponta para o último commit (confirmação) que você fez.
Working Area, Staging Area, Repository:
The Working Area:
It's the Area that currently holds all your physical files you're currently working with
in the current branch.
The Staging Area:
It's a Memory Buffer Area that holds all file modifications/insertions you've done
so at the moment. Moving to a different branch will also move the Staging Area with the same
modified/inserted files from the branch before. Which will need to be either commited or dropped.
The Repository Area:
Whenever you type 'git commit -m "MyCommit"' you're applying the changes in the staging
area to the the Repo. -- NEEDS TO CHECK
To summon it up, this is how it goes:
GIT ADD will add changes made to the 'Working Area' to the 'Staging Area'
GIT COMMIT will add changes made to the 'Staging Area' to the 'Repository Area'
GIT CHECKOUT -- file will remove changes made to the Working Area FROM the Staging Area
and UNDO them - BEFORE THEY ARE COMMITED
GIT RESET
will undo changes made to the Working Area from the Repository Area
AFTER they've ALREADY been commited to the Repository Area
Example: typing 'git diff' will show all diferences between the Working Area and the Staging Area
'git diff --staged' will show differences between The Staging Area and the Repo Area.
'git diff ' will show differences between Different Repos
Importante Notes:
On Git branches are just a reference for a commit
---IMPORTANT GIT LOG NOTES----
git log --onoline --decorate
*you can type cat .git/HEAD to show where you actually are
*HEAD == WHERE YOU ARE
*switching branches will switch the files at the Workspace Area
*git log #shows all commits - check
*git log --all #shows commits that are ahead of that branch
normally 'git log' only shows commits done up to that moment
that the branch was located.
*git log --oneline --graph #shows divergence between branches.
example: when you have made modifications/merges in different branches
this will make git show divergences/merges between branches.
git log --graph
*Fixing Merge Conflicts:(GIT MERGE & GIT MERGE --ABORT)
What happens when you make modifications on the same file at different branches and then
try to merge? git will warn you about conflict, and SET THE WORKING AREA with the conflictuous
file(s) - note.: if merge runs without conflict, there is neither files to be added nor commits -
then you can just open the file in a normal text editor and edit it to
fix the conflicts.
After that's done you can finally add the modifications done into the Working Area
to the Staging Area with 'git add ' and then commit the
modifications to the Repository Area with ' commit -m <"commitname"> '.
Alternatively you can drop modifications with 'git merge --abort' to abort merge.
The second syntax ("git merge --abort") can only be run after the merge has resulted in conflicts. git merge --abort will abort the merge process and try to reconstruct the pre-merge state
FILE STATUS LIFECYLE:
There are 4 File Status:
1 - Untracked
When files are added to the Working Area, but are not being Tracked.
using 'git add ' will start tracking them, adding them to the
Unmodified Status.
When files are Untracked, git will not touch them when moving between branches or commits!
they'll be left untouched by git's engine! - VERY IMPORTANT
2 - Unmodified
Files are kept as unmodified status after being tracked,
editing a file will turn them to Modified Status.
Renaming/Moving a file will set them as have been deleted.
And the Renamed/Moved file will be set as untracked.
Same thing happens if files get Renamed/Moved AFTER being Modified.
*After the files have been moved/rename, undoing changes will require the
'old' file to be 'git checkout -- ' and the new files to be manually
deleted.
3 - Modified
After files are being tracked and get some modification through editing,
they receive a Modified Status, these files will require to be added to the
Staging Area with 'git add ', thus turning them into the Staged Status.
4 - Staged
Staged Status is the final step in the File Status Lifecycle of GIT
before they are finally commited to the Repository, thus making permanent changes.
to move a file from the Staging Area(staged status), all that's needed is to make
a commit 'git commit -m <"commitname">'.
http://thomascgreen.com/tech/?p=7
https://latedreamer.blogspot.com/2016/11/working-directory-staging-area.html
-----------------------------
*Note, some of the description bellows need to be updated with the Staging Area Eplanation
git --help or man git
git help config #gets help about configuration
git config --global user.name "Your Name"
git config --global user.email "Email Address"
git config --list
git config --global core.editor nvim #sets nvim as main text editor for git
git init #Initilizaes empty Git repository in .git/
creates a .git folder inside the workspace directory - creates a git repository
ex.: ~/MyGitProject/ by typing 'git init' makes it starts a new repo on it
on a hidden .git folder
git add #This command updates the INDEX using the current content found in the working tree
^ before commiting those changes.
#a 2nd 'git add' to an already added file, allows to save unmodified
^ files onto the repo.
git add * #Recursively adds all files to the INDEX(Staging Area)
git add . #Same as above
git add Documentation/\*.txt #Adds all .txt files under that directory to the INDEX(Staging Area)
git add git-*.txt #Adds all files that start with git- and ends with .txt to the INDEX(Staging Area)
(note.: all files under the Staging Area will need to be commited)
git restore --staged B.txt #Removes B.txt from the Staging Area
git ls-remote #List references in a remote repository along with the associated commit IDs
--- HOW TO IGNORE FILES FROM BEING TRACKED/UNTRACKED ---
1 - Create a file called .gitignore,
2 - Add the following content as follows:
*.o
*.jar
*.exe
libraries/
3 - then add to the Staging Area: git add ./.gitignore
4 - finally commit it: git commit -m "IgnoringFiles"
Source: https://git-scm.com/docs/gitignore
ADVANCED COMMANDS:
git log --graph --abbrev-commit --oneline --all --reflog #SHOWS ALL COMMITS
--------------------------------------------------------
Study Source: https://www.w3schools.com/git/
git status #Shows modified files, unmodified files, tracked, untracked, and staged files
git log #Shows all commits that have been done
git log --oneline #Shows 1 commit per line
git reflog #Shows all commits, INCLUDING branch merge commits - VERY IMPORTANT
git reflog #Shows all Heads
git branch #Shows all branches
git branch -d #Deletes Branch / Removes Branch
git checkout -b #Creates branch from current commit or commit_id
git commit #Opens default text editor for both: naming commit and choosing
files to commit
git commit -a #Commit current work with an editor
git commit -m "Commit 1" #Commmits all currently added files, and names commit as "Commit 1"
git commit -m "Commit 1" File1.txt #Commits changes made to File1.txt, names commit as "Commit 1"
git commit [filename] -m "message" #Commits a single file in the current branch
^ you can check which files can be commited using git status
git commit --amend -m "message" #Fixes/Reverts current head(previous commit) message(commit message)
^ on a remote repo, it'll be required to use git pull right afterwards
^ and make a new commit.
git commit --amend #Allows to edit the current head(previous commit) without actually creating a new commit
^ Hint.: Modified files should be added with git add,
and then git commit --ammend should be used to edit commit message
git commit -a -m "Commit Message" #Git adds all files and creates a new commit / Makes a new commit
git commit -a --amend #Git adds all file modifications and edits the last commit
^ Useful for changing/editing commits
git commit -m "Message" #Commits changes to a given file.
^ VERY IMPORTANT: you can auto-complete directory/filenames using key
^ ex.: git commit ./source/Main
^ will auto-complete to: ./source/MainComponentes/StaggedFile.cpp
git restore #Restores git working tree: reverses/undoes any change made to the working/staging area
^ VERY IMPORTANT: you can auto-complete directory/filenames using key
^ ex.: git restore ./source/Main
^ will auto-complete to: ./source/MainComponentes/StaggedFile.cpp
git stash #Saves current working tree instead of reversing/undoing it, and stashes it away.
git stash pop #Opens stash within current working tree for commiting.
git stash list
git stash help
source:
http://git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages
git rm #removes a file from being Tracked AND DELETES IT SAFELY
git rm -f #forcefully removes a file from being checked AND DELETES IT
git rm --cached #removes a file from being checked, retainning the original file
^remove a file from being tracked with --cached flag, will also require
file to be physically removed.
git mv #Moves/renames files withing git
git switch #Switches to a different branch
git checkout - #Goes back to where previous HEAD was set
git checkout -- #Discard changes from being made in the commit AND UNDOES them,
setting them to their original previous state
^- Use in case File has been Modified/Updated
Checkout only works for undoing changes in the staging area.
git checkout #Sets HEAD into given branch
git checkout #Goes back to the previous commit changes!
git checkout -b #Turns all current work into a new Branch without commiting
git branch -d #Deletes Branch / Removes Branch
git revert #Pulls out any modification made by a given commit in such a way that it would be like
if the commit has never happened. Avoid using this in public/remote repos.
git reset #Resets the working space/staging area to that of the given commit
^This reset also sets all of the staging area from the given commit before the commit was realized.
changes that have been made to the given commit, will also have to be "recommited" if you intend on keeping those changes ONLY.
always checkout the changes with git diff after reset.
git reset --hard #Undoes commits, Reverses Current Working Space to the one in the Given Commit State
^ if file has been forcibily removed, git checkout -- is needed.
NOTE.: Checkout can't discard nor undo changes that already have been commited
'git reset' undoes changes made permanently - Need to check
git reset --soft HEAD~1 #Undoes commit to the previous commit/HEAD state.
^ Does not touch the index file or the working tree at all
(but resets the head to , just like all modes do). This leaves all
your changed files "Changes to be committed", as git status would put it.
git reset --hard HEAD~1 #Undoes commits and sets it to the previous commit_ID/HEAD state
Resets the index and working tree. Any changes to tracked
files in the working tree since are discarded.
git reset --mixed HEAD~1 #DEFAULT BEHAVIOR: Resets the index but not the working tree (i.e., the changed files
are preserved but not marked for commit) and reports what has not been updated.
This is the default action. If -N is specified, removed paths are marked
as intent-to-add (see git-add(1)).
git reset --keep HEAD~1 #Resets index entries and updates files in the working tree that are different
between and HEAD. If a file that is different between and HEAD has
local changes, reset is aborted.
in other words, reset only occurs if same existing files have no difference between
them in the different commit_ID/HEAD States.
git reset --merge HEAD~1 #Resets the index and updates the files in the working tree that are different
between and HEAD, but keeps those which are different between the index
and working tree (i.e. which have changes which have not been added). If a file
that is different between and the index has unstaged changes, reset is
aborted.
In other words, --merge does something like a git read-tree -u -m ,
but carries forward unmerged index entries.
(note.: check man pages for actual examples -> $man git-reset)
git stash #Saves all uncommited work, for committing later on any branch/head
git stash pop #Opens the stash for commiting in any branch/head
git diff stash #Checks difference between HEAD(or Branch) and Stash
git branch #Lists all branches in existance
git branch #Creates a new branch
git branch #Creates new branch from old_branch commits
git branch -d #Deletes a branch
git switch #Switches to a different branch
git reset HEAD [filename|branchname] #Undoes file or branch deletion
git checkout #Switches current branch to
git checkout -b #Creates new branch with all the current branch commits and
^ automatically switches to it.
git checkout -b #Creates a new branch called new_feature with master branch commits
^ and switches to it.
git diff #Checks difference between two different branches
git diff stash #Checks difference between HEAD(or Branch) and Stash.
git diff #Checks difference between Head(or branch) with branch_id.
git merge #Commits new modifications from to the CURRENT actual branch
you're working with, ex.: git checkout master
git merge newbranch
^Will merge all modifications from newbranch to master branch,
It's now possible to safely delete newbranch if not needed.
git merge #Merges New Commit into Currrent Branch
Note.: You can only Merge Commits
^ Warning: Running git merge with non-trivial uncommitted changes is discouraged: while possible,
it may leave you in a state that is hard to back out of in the case of a conflict.
git merge --abort #The second syntax ("git merge --abort") can only be run after the merge has resulted in conflicts.
^ git merge --abort will abort the merge process and try to reconstruct the pre-merge state.
warning: avoid using with uncommited changes on INDEX!
git merge --continue #The third syntax, can only be used when merge conflicts has appeared.
git mergetool #Executes tool for resolving merging conflicts manually
^Requires merge tool to be set and configured.
git rebase #Merges ALL OF THE COMMITS from a given branch into the current one!
The difference between git merge and git rebase is that git merges
only merges the last of commit of a given branch into the current commit of
the current branch; however, git rebase merges ALL OF THE COMMITS into the
current branch?? - NEEDS TO CHECK - WRONG!
Rebase will present conflicts one commit at a time whereas merge will present them
all at once. It is better and much easier to handle the conflicts but you shouldn’t
forget that reverting a rebase is much more difficult than reverting a merge if
there are many conflicts.
Rebase Golden Rule: Never use rebase on a public/shared branch, only use rebase
if you're the only developer of a given branch!
^public branches are branches that other people might have checked out. If you’re
developing a branch on your own and not sharing it with anyone, you could rebase it
to keep the branch up to date with respect to the main branch.
Moreover, the main branch can move forward with a fast-forward merge rather than
a regular merge commit. Rebasing rewrites history, and anyone having branches that
were checked out of the history you just unmade will be sad, angry or worse.
That’s one reason you can’t just push rebased branch on GitHub
(unless you force it and sacrifice a kitten). So just say no. Rebasing private
branches is perfectly fine, and in fact often done when squashing or rearranging
commits, cleaning up a branch before going public with it, or just updating
long-running feature branch (go easy on the last one, though).
source: https://www.benmarshall.me/git-rebase/
git rebase --onto #Rebases branch_1 and branch_2 onto base_branch
git rebase --onto topicA~5 topicA~3 topicA #Removes Commits from 3rd(excluded) to 5th(included) from
being rebased. *included: 5th gets removed.
This is useful if F and G were flawed in some way,
or should not be part of topicA. Note that the argument
to --onto and the parameter can be any valid
commit-ish. - NEEDS TO CHECK
git rebase --continue #Continues rebase after conflicts have been solved
git rebase --abort #Aborts & Reverts rebase in case of conflict
-- HOW TO DROP MODIFICATIONS FROM STAGING AREA --
git restore --staged B.txt #Removes B.txt from the Staging Area
git restore #Also works as of date: 2021
-- HOW TO REVERT COMMITS --
Once you have made an accidental commit in your LOCAL REPO by mistake,
it's possible to revert it by checking the last commits you've made with:
git log
then pick the commit ID you want to revert to and do a checkout in it:
git checkout
if you're working on only 1 branch, you'll need to make a spare one:
git branch backup
finally delete the branch that has been commited by accident:
git branch -d
^ note.: this isn't a good idea, because it'll erase all that branch's history
recreate it:
git branch
Now your accidental commit should be reverted.
--------------------------
--------------------------
ADVANCED GIT:
man pages and tldr are the best place for checking out git command examples,
for example:
$man git-log #The bottom-page displays a small list of examples for git-log commands.
$tldr git-log #Requires tldr Installed
----GIT LOG:
git log --graph --abbrev-commit --oneline --all --reflog #SHOWS ALL COMMITS
git log --no-merges #Show the whole commit history, but skip any merges
git log v2.6.12.. include/scsi drivers/scsi #Show all commits since version v2.6.12 that changed any file in - VERY IMPORTANT
^ the include/scsi or drivers/scsi subdirectories
git log --since="2 weeks ago" -- gitk #Show the changes during the last two weeks to the file gitk.
^ The -- is necessary to avoid confusion with the branch named gitk
git log --name-status release..test #Show the commits that are in the "test" branch but not yet in the - IMPORTANT
^ "release" branch, along with the list of paths each commit modifies.
git log --follow builtin/rev-list.c #Shows the commits that changed builtin/rev-list.c, including those commits
^ that occurred before the file was given its present name.
git log --branches --not --remotes=origin #Shows all commits that are in any of local branches but not in any of remote-tracking
^ branches for origin (what you have that origin doesn’t). - IMPORTANT
git log master --not --remotes=*/master #Shows all commits that are in local master but not in any remote repository master branches. - IMPORTANT
git log -p -m --first-parent #Shows the history including change diffs, but only from the “main branch” perspective,
^ skipping commits that come from merged branches, and showing full diffs of changes introduced
by the merges. This makes sense only when following a strict policy of merging all topic branches
when staying on a single integration branch.
git log -L '/int main/',/^}/:main.c #Shows how the function main() in the file main.c evolved over time. - VERY IMPORTANT
git log -3 #Limits the number of commits to show to 3.
----GIT LOG(2):
git log -p #Show the history of a particular file or directory, including differences. - VERY IMPORTANT
git log --stat #Show an overview of which file(s) changed in each commit. - VERY IMPORTANT
git log --oneline --graph #Show a graph of commits in the current branch using only the first line of each commit message. IMPORTANT
git log --oneline --decorate --all --graph #Show a graph of all commits, tags and branches in the entire repo. - IMPORTANT
git log -i --grep search_string #Show only commits whose messages include a given string (case-insensitively).
git log -n number --author=author #Show the last N commits from a certain author. - VERY IMPORTANT
git log --before="2017-01-29" --after="2017-01-17" #Show commits between two dates (yyyy-mm-dd). - VERY IMPORTANT
---- GIT COMMIT
git commit -m "message" #Commit staged files to the repository with a message.
git commit --file path/to/commit_message_file #Commit staged files with a message read from a file.
git commit -a -m "message" #Auto stage all modified files and commit with a message.
git commit -S -m "message" #Commit staged files and [S]ign them with the GPG key defined in `~/.gitconfig` - VERY IMPORTANT
git commit --amend #Update the last commit by adding the currently staged changes, changing the commit's hash. - VERY IMPORTANT
git commit path/to/file1 path/to/file2 #Commit only specific (already staged) files.
git commit -m "message" --allow-empty #Create a commit, even if there are no staged files. - VERY IMPORTANT
---
-- THE FOLLOWING BELOW NEEDS TO BE MORE EXPLAINED!! --
git remote #lists all local and remote repos
git remote rm #deletes repo
git remote add origin #creates local repo on pre-existing path
^ example: git remote add origin ~/gittest/REPO/
git remote add origin https://github.com/marcelojo/artigo_git.git #creates a remote repo called origin
git clone #Creates a local repo based on a remote repository
example:
git clone https://github.com/marcelojo/artigo_git.git
git push #Pushes current branch modifications into remote one
git push -u #Sends modifications from branch to remote repository
example:
git push -u origin master
git pull #Incorporates changes from a remote repository into the current branch.
^ In its default mode, git pull is shorthand for git fetch followed by git merge
FETCH_HEAD. More precisely, git pull runs git fetch with the given parameters
and calls git merge to merge the retrieved branch heads into the current branch.
With --rebase, it runs git rebase instead of git merge.
ex.: git pull origin
---MISC COMMANDS---
git config color.ui true #sets colored output
git config format.pretty oneline #exibir logs apenas uma linha por commit
git add -i #fazer inclusões interativas
gitk #interface padrão do git
git tag 1.0.0 1b2e1d63ff #rotulando um commit ID
---GIT HEAD COMMANDS---
OBS.: Note that both MASTER and HEAD are pre-existing branches - RE-EXPLAIN
so in order to switch back to master do: git checkout master
You also can't move from HEADs to BRANCHES when making changes without COMITTING them
first on the master branch. you can, however, if you are in another branch. - RE-EXPLAIN
After merging different branches, it's necessary ADD or REFUSE each changes and make a new commit in
case you have accepted any changes.
git reflog #Lists all history of head movements
git checkout HEAD^ #Goes to the previous COMMIT by 0 or 1
git checkout HEAD~ #Goes to the previous COMMIT by Nth - Needs Check
git checkout HEAD@{} #Goes to Nth Head - check rflog
git checkout #Goes to the head ID
git branch 35e6ab4 #Creates a new branch with all modifications from head ID
^ it differs from git checkout -b "new branch", because 'checout -b' doesn't requires ID, and
it 'checkout -b' not only creates a new branch, but also switches you to it whereas 'branch'
doesn't do that. also, what 'branch' does is simply copy one branch/head to another.
'checkout -b' is useful when you've made modifications to the working area, and want to bring
modifications to a new branch, instead of modifying the original branch.
Whenever you want to make a modification to the master branch, do the following: - REVIEW
git checkout HEAD~ #ID Number of commit
... make modification to files...
git add #Adds Modification to current head
git commit -m #Makes a new commit with all the added modifications
git checkout master #Switches to Master Branch
git merge #Merges New Commit into Master
Note.: You can only Merge Commits
*Note.: Whenever you make modifications to a HEAD's Files, you need to either ADD modification
or UNDO them either with: 1 - git reset HEAD #same as below, but for undoing deletion
git checkout -- #for undoing changes
or
2 - git add #for confirming file modification/insertions
And then finally commit those changes with 'git commit -m "New Commit" [filename]',
only then you'll be able to switch branches/head
*Note: You can save Head IDs on different VIM Registers, so you don't need to 'git reflog' all the
time.
git reflog example:
35e6ab4 (HEAD) HEAD@{0}: checkout: moving from 0a028cb8ff4af74ec2cdc0d4c953b015121dc81a to HEAD@{20}
^ HEAD@{0} - HEAD Number on List History
everytime there's a head movement, there will also be a new head number added at the end
of the list.
^ Checkout: Moving from XYZ to HEAD@{20} #Shows the operation that has been done, and the movement.
--- GIT END TUTORIAL ---