pattern: http://<site_name>/<repo_name>/commits/<commit_hash>
eg:
If you remove the trailing “s” from “commits”, you will see a diff of that commit vs the previous.
pattern: http://<site_name>/<repo_name>/commits/<commit_hash>
eg:
If you remove the trailing “s” from “commits”, you will see a diff of that commit vs the previous.
The pain — a big commit touches on too many files, 3 of them major changes, while 5 files have cosmetic changes. In git-diff or git-difftool, I want to focus on the 3 major files.
Some developers would want to split the big commit into a “major” and a “cosmetic” commit, but one of the snapshots would be half-cooked and unusable. In such a case, the commit comment would warn “This commit is part of a bigger change. Please do not build this commit alone”.
As an alternative we can make the 3 major files show up first (or last) in diff. You can put the content below in src/diffOrder.txt and use it as instructed. All unspecified files would show up in natural order.
The line-ending issue the most common mistake with -O !
# git diff -O src/diffOrder.txt # check EACH line below to ensure unix line ending, # even if entire file is unix-style. # wildcards are needed below. */ProductCacheUtil* */CSV* */FutureDataCacheUtil.java */RJOBRIENDROPTools.java
— based on https://stackoverflow.com/questions/2529441/how-to-read-the-output-from-git-diff
@@ -18,6 +19,8 @@ int cmd_http_fetch(int argc, const char **argv, ...
It is in the format @@ from-file-range to-file-range @@ [header]
. The from-file-range is in the form -<start line>,<number of lines shown>
, and to-file-range is +<start line>,<number of lines shown>
. Both start-line and number-of-lines refer to position and length of hunk in preimage and postimage, respectively. If number-of-lines not shown it means that it is 0.
The num-of-lines in the preimage can mean the number of context lines. This is the case when the change is insert.
The num-of-lines in the postimage includes context lines too.
git diff –color-words
git show –color-words someCommit
git diff <commit> path/to/file
My shell function below can quickly show diff between a given past commit to the current tip.
You need to hardcode the filename(s) under investigation.
rollback() { # roll back to a given commit target=$1 #some git commit id pushd /N/repos/MI_EPA/ git diff head --name-status set -x git checkout $target -- tbl/Generic/ReplaceOrder.tbl # bin/javagen.pl #tbl/MSF/NewOrder.tbl git diff HEAD --name-status # git diff alone won't work # above command should reveal only the named files changed. git diff HEAD set +x popd }
— to sort git tags by date: https://bintanvictor.wordpress.com/wp-admin/post.php?post=36920&action=edit&classic-editor
Sometimes, a tmp file gets added to staging, often automatically 😦 This file is still needed in the workTree, so we can’t reset-hard 😦
To transform this “change” from staged to unstaged,
git reset tmpFile # works even though tmpFile is actually untracked 🙂
Key question — Q1: which commit would have multiple parents?
— scenario 1a:
In this simple scenario, your merge is a fast-forward merge. The updated master would now show hash1 at the tip, whose only parent is hashJJ.
A1: No commit would have multiple parents. Simple result. This is the default behavior of git-merge.
Note this scenario is similar to https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-request-merges#rebase-and-merge-your-pull-request-commits
However, github or bit-bucket pull-request flow don’t support it exactly.
— scenario 1b:
Instead of simple git-merge, what about pull request? A pull-request uses q[ git merge –no-ff brA ] which (I think) unconditionally creates a merge-commit hashMM on maser.
A1: now hashMM has two parents. In fact, git-log shows hashMM as a “Merge” with two parent commits.
Result is unnecessarily complex. Therefore, in such simple scenarios, it’s better to use git-merge rather than pull request.
https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-request-merges explains the details.
— Scenario 2: What if ( master’s tip ) hashJJ is Not parent of hash1?
Now maser and brA have diverged. I think you can’t avoid a merge commit hashMM.
A1: hashMM
— Scenario 3: continue from Scenario 1b or Scenario2.
3. Then you commit on brA again , creating hash2.
Q: What’s the parent node of hash2?
A: I think git actually shows hash1 as the parent, not hashMM !
Q: is hashMM on brA at all?
A: I don’t think so but some graphical tools might show hashMM as a commit on brA.
I think now master branch shows hashMM having two parents (hash1+hashMM), and brA shows hash1 -> hash2.
I guess that if after the 3-way-merge, you immediately re-create (or reset) brA from master, then hash2’s parent would be hashMM.
Note
In Git, a commit message is immutable but…
… but github supports editable comments on a commit or pull request 🙂
Warning — may not work if there’s a recent merge-in on your branch
Find the target commit and its immediate parent commit.
git rebase -i the.parent.commit
First commit in the list would be your target commit. Use ‘r’ for the target commit and don’t change other commits. You will land in vim to edit the original bad commit msg. Once you save and quit vim, the rebase will complete, usually without error.
Now you can reword subsequent commit messages.
— https://stackoverflow.com/questions/4404444/how-do-i-git-blame-a-deleted-line
$ git log -G $someRegex --oneline the/file
— https://dev.to/miku86/git-find-specific-deleted-content-in-a-file-5h33 shows two solutions
git log -p –full-history -S ‘newsletter’ — the/file
git push --force-with-lease
This option is a safer version of push-force.
It will not overwrite any work on the remote branch if more commits were added to the remote branch (usually by another team-member). It ensures you do not overwrite someone else’s work by force pushing.
— to list commits on a single file
git log the/file # works for me all the time git log --follow the/file # Continue listing the history of a file beyond renames.
github -> view the file -> top right shows “Raw|Blame|History” -> History
https://emmanuelbernard.com/blog/2014/04/14/split-a-commit-in-two-with-git/:
git rebase -i <oldsha>
# bring the bigCommit to the tip
git reset HEAD^ # reset to just before that new tip
git add file1
git commit -m "First file"
git add file2
git commit -m "Second file"
A git tag can have two dates (and author, and msg)
A lightweight tag has no tagger date (or tagger name or msg)
When you run ‘git show myTag’ you will see the tagger date ( and tagger name + msg) only if the tag is an annotated (a.k.a heavyweight) tag.git
— sort by date
git tag –sort=-taggerdate # may not work well for lightweight tags
git log --tags --simplify-by-decoration --pretty="format:%ci | %d" |sort -r
Consider the harmless-looking command git commit –am
Most of the time, I rely on this command as a safe way to amend commit message without touching the original files in the commit.
However, if there’s further changes on file1 in staging, then this command would silently introduce this change into the commit. Once you finalize the commit message and save it, this change inadvertently becomes part of the commit !
categoryX/branchY convention is popular and well-supported so I use
Scenario — the tip of your master branch is a merge commit.
The BitBucket commit history page won’t show the merge commit hash. It shows the incoming commit’s hash.
However, the BitBucket Compare page would show the merge commit’s hash at tip of the branches.
— post-commit hook runs after the commit is completed and closed. So I don’t think it can modify or cancel the commit.
— pre-commit hook can’t distinguish a Amend vs a regular Append.
git config –global core.safecrlf false
— bcomp advantage over git-diff
bcomp shows byte count in new vs old versions… can detect intrafile cut-paste
— based on http://www.scootersoftware.com/support.php?zz=kb_vcs#gitwindows
git config --global diff.tool bc git config --global difftool.bc.path /c/Progra~1/BeyondCompare4/BComp.exe git config --global difftool.prompt false The above sets up git-difftool but how about git-diff? I feel one of the two is sufficient. git config --global merge.tool bc git config --global mergetool.bc.path /c/Progra~1/Beyond~1/BComp.exe
— no integration with git-diff?
Think again. If your git-diff always uses a GUI, then you can’t get the console UI which is frequently valuable. Therefore, it’s a good thing that you can’t modify git-diff.
—
http://www.scootersoftware.com/support.php?zz=kb_vcs#gitwindows worked for me, including a 3-way merge GUI —
git mergetool feature/my_br6 origin/feature/my_br6 -- buildChoops.sh |
Multiple descendant — very common…. branching scenario
2 parents — also common …. merging in a branch
git checkout <commit> path/to/file
git diff # shows nothing as the local change is in index
git diff HEAD # shows the diff between the HEAD version and rollback version
Background — Suppose you made 3 commits on your feature branch name “parix”, but meanwhile, someone added 4 commits in master branch. Therefore there is now a divergence in the commit history graph.
Often times you need to visualize the divergence. You need to exactly what 3 commits are on your branch after the common ancestor.
git log master..pairx # listing the 3 additional commits in pairx branch, right after the common ancestor i.e. the branching point
git log pairx..master # to show those 4 commits.
I prefer cherry-pick.
Often the merge/rebase/cherry-pick/stash-pop operation would silently put some of the changes in _staging_, therefore git-diff would fail to show them. I have to use git-diff-HEAD instead:(
–If you have no choice then here’s the standard procedure
Two simple steps:
git stash #no args
# Now git diff will no longer show the uncommitted changes:) …later
git stash pop
# Now git diff shows the original uncommitted changes
If git-stash-pop hits conflict on 1 file out of 3
https://confluence.atlassian.com/bitbucketserver/keeping-forks-synchronized-776639961.html says
Fork syncing helps you to keep your fork in Bitbucket Server up-to-date with changes in the upstream repository. Bitbucket Server can do this automatically for all branches (and tags) you haven’t modified in the fork.
I guess forking (and pull request) is not a feature of GIT per se but a feature of Bitbucket and GitHUB server. I think the server get notified upon a new commit and runs fast-forward git pull.
For me, rebase is the procedure to re-sequence commits… A simple form of history rewrite.
git pull --rebase # moves your local commits to the end of the linked list
The following will take the last five commits and give you an interactive session that allows you to (optionally) merge them.
git rebase -i HEAD~4 |
More details are here http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html
git diff –help # manpage
git diff –color-words # good
git diff -U22 # 22 lines of context
3 forms of diff — See 3trees@git
— diff of a merge-conflict file is different.
I think it is a 3-way diff. Output shows current “merged” file vs orig1 and orig2. https://git-scm.com/docs/git-diff#_combined_diff_format explains “++”
— if you see a line showing up due to nothing but white space change, you can usually use “-w” to suppress it but sometimes you need to pinpoint the white space change:
git diff |cat -vet
— on linux, git-diff output seems to truncate long lines
https://stackoverflow.com/questions/136178/git-diff-handling-long-lines shows
git config core.pager 'less -r'
I didn’t like git-revert as it complicates history. See https://www.atlassian.com/git/tutorials/undoing-changes/git-revert
git checkout HEAD -- <file or directory> |
This use of git-checkout is unrelated (as far as I know) to the commit-level checkout. This solution is officially /sanctioned/ … Some git commands would suggest …
(use "git checkout -- <file>..." to discard changes in working directory)
git reset --hard HEAD # reverts tracked files back to the head git clean -fxd . # deletes untracked files in current dir. You may want to cd to the repository base first |
[Victor] My vote for best explanation of git-reset goes to https://git-scm.com/blog/2011/07/11/reset.html. Detailed, but more readable than the manual. Many examples are useful to me.
Warning — if you want to temporarily play with an older version of file1.java, then be careful. Make sure you save the current tip of your branch. If you git-reset–hard then you may lose that tip!
git fetch origin git reset --hard origin/yourBranch |
Say you are working on a feature branch with other people, with you all making commits and pushing to the remote replica of this branch. At some point you will want your commits merged with develop/production. Git does provide a method of choosing which commits you would like to push. The easiest way to explain this is with an example. We assume that all the following commands are run in a command line tool.
git checkout feature/commodity git log - 3 --pretty=oneline #look at the 3 most recent commits to the repository (includes all commits to all branches - in a nicely displayed format) $ git log - 3
|
Looking at this log, I want to push only the latest change to ‘develop’ branch (via a pull request), the commit associated with the e5a67d7088622dd8821dfdd8e2fafa2dc938b75c hash number. Keeping a record of this hash number I then create a new feature branch from ‘develop’ branch in Stash. Assume this new branch is called feature/cherry_pick
git fetch #update local repo to get this new branch info git checkout feature/cherry_pick # switch to this new branch, at the moment is exactly the same as origin/develop git cherry-pick e5a67d7088622dd8821dfdd8e2fafa2dc938b75c #where the hash number is the commit I actually want to merge into 'develop' git commit #commit this change to the local feature/cherry_pick git push #push this change to the remote feature/cherry_pick branch |
You can now create a pull request in Stash to merge this cherry-picked commit into ‘develop’
–Method: git-diff command
This is a basic but versatile tool. It looks at two commits you provide. Note each tag represents a commit. Each branch name also represents the commit at the tip of the branch.
–Method: have two local repos (clones) to check out different branches
–Method: download remote version as complete file, then diff that against local file
Here’s my earlier favorite choice to diff a remote branch version vs a local branch version:
mv buildChoops.sh buildChoops.local git checkout origin/feature/my_br6 buildChoops.sh # download the file from the remote branch into the current directory locally ... now run any diff tool between the two files |
–Method: git diff using Beyond Compare 3
See more details in separate blogpost git+beyondCompare
–Method: git diff using Winmerge
see http://stackoverflow.com/questions/1881594/use-winmerge-inside-of-git-to-file-diff, updated June 2015
I hope there are similar solutions for other diff GUI tools.
A common situation: you make many incremental, quick and dirty commits on your branch, undoing and redoing changes. You don’t need to push the entire history to a shared branch like Develop.
Many solutions exist. Git offers many commands to rewrite history on a branch. Many git users use them regularly. We could use them to clean up the commits on a feature branch before pulling them into a pull request. Here are some of the methods.
This will rewrite the history of your branch, you should only do this if no one is sharing your branch (or you don’t care about them).
This example will let you interactively select from the last four commits.
git rebase -i HEAD~ 4 # Alternatively, specify the last-good commit: git rebase -i e8a9cf093 # Rebase all subsequent commits |
git tag backup # we do this so that we don't lose our history git checkout -B temp origin/develop # checkout a clean temporary branch from develop git merge --squash <branch> # merge our old branch in, squishing all the commits git commit git branch -f <branch> temp # force the branch to point at the new commit |
Suppose you have 5 commits to squash,
git reset --soft <a previous commit hash, or something like HEAD^ 5 > # rollback to the named commit. # reset --soft modifies only commit history, not work tree or index. # Now you can look at the files involved in those 5 commits, staged for the next commit git diff --cached --name-status git commit -m 'your msg' # git push ... and create pull request |
All methods so far assume the complicated commit history is in local repo not on a Stash branch. If your Stash branch has stuff you want to pull into Develop, but your Stash branch has complicated history, then …
# create the candidate_branch from Develop, on stash git tag backup # we do this so that we don't lose our history git fetch # will show the new branch git checkout candidate_branch git merge --squash old_branch # merge our old branch in, squashing all the commits git commit # the default msg shows list of files. you might want to uncomment that in the msg. git push origin candidate_branch # now the candidate branch is up-to-date on Stash. Ready for pull request. |
# clean up your local branch as illustrated above git push --force origin your_Stash_branch # overwrite the Stash branch and overwrite public history - Dangerous! |
The git-rebase and git-cherry-pick commands often fail in the presence of a complicated history of merges, file deletes etc. Try filter-branch.
# clean up the branch xyz git checkout -b xyzRewrite # Always do the rewrite on a cloned branch please git filter-branch --force --msg-filter 'sed "s/addYENRates/[CFMQUANT-262] addYENRates/" ' e635d034ea8..HEAD |
At end of the command, 1st hash is the parent of the flawed commit. 2nd hash must be HEAD (or perhaps the name of a branch).
Command should tell you the branch is rewritten. If no commit message matches the pattern, then the command would tell you the branch is left unchanged, so it’s safe if you have a typo that matches nothing.
In either case, you can then run git diff against the original branch and verify they are identical content-wise.
In this real example we were lucky the message “addYENRates” was rather unique. If it shows up on 2 commits, then both would be rewritten.
git remote -v # will show the URL
Scenario: throughout the month, your main branch takes in many pull-requests. You want to see the sequence of merge points in chronological order.
On BitBucket, the commit listing is chronological but doesn’t show the merge commits. I usually unhide the merge commits, so on my page the merge commits are interleaved with “regular” commits in chronological order like
The regular commits line up according to their commit timestamps. the most recent merge could have its one and only commit created months ago !
What I want is “nothing but the merge points”. I think I have to ignore the “regular” commits and only look at the merge commits.
I always want a long description for my git branch. Not sure how best to do it. https://stackoverflow.com/questions/4750845/how-do-you-annotate-a-branch has some suggestions.
— Git tag can have an annotation:
git tag -a newTag some_commit #create
git show newTag #reveal the annotation, creation time etc
git tag -d newTag #deletes the tag
Two ways to edit annotation:
git tag <tag name> <tag name> -f -a
I often need to delete
git pull --prune # deletes ALL remote-tracking branches
git push origin --delete remote_Branch # deletes remote and remote-tracking
git branch -D local_Branch
Error comes from winpty when I try to redirect the python script output.
Sugg: try python.exe without winpty like
python.exe script1.py |less
Tested briefly.
Complication — …/theRepo/.git exists but …/theRepo/src/.git may not
git_ps1(){ dd='.git' [[ -d $dd ]] || dd=` pwd |perl -pe 's|(/repos/M\w+).*|$1/.git|' ` [[ -d $dd ]] && git rev-parse --abbrev-ref HEAD 2>/dev/null } export PS1='\n\s!\! \u@$Host [ \t \d ] \w/ $(git_ps1) \n\$ '
By default there’s a default-enabled highlight (in red) of trailing spaces. I encounter it all the time when running git-diff. Extremely distracting.
Beware: when you copy-paste into a command window, the dash may become something else 😦
If successful, this command adds a line into .git/config like
whitespace = -trailing-space
You can remove this line to restore the “factory default”.
shows q(:cq) is the vi command to kill the pending commit
q( :q! ) didn’t cancel the commit 😦
git clean -n #dry-run
git ls-files -o #also works but harder to remember
I still don’t know how to list all files each with a status like uncommitted/untracked/committed
Personal best practice. Git History rewrite is not always no-brainer and riskless. Once in 100 times it can become nasty.
It should Never affect file content, so at end of the rewrite we need to diff against a before-image to confirm no change.
The dumbest (and most foolproof) before-image is a zip of entire directory but here’s a lighter alternative:
Note the branch name can be long but always explicit so I can delete it later without doubt.
git config --global credential.helper wincred
$ git config credential.helper store
$ git push
Username for 'https://github.com': <USERNAME>
Password for 'https://USERNAME@github.com': <PASSWORD>
git config --global user.email {ID}+{username}@users.noreply.github.com
You can find it in https://github.com/settings/emails
–for current dir
git checkout .
–for a single file
git checkout a/b/file # tested
In q[ git branch -a ], we see
remote/origin/branch1
remote/origin/br2
…
I verified that
q[ git log remote/origin/br1 ] and q[ git log origin/br1 ] are identical
–To delete a local tracking branch without deleting the remote branch:
git branch -rd origin/br2
— my incomplete understanding:
There can be many remotes in a git repo. Each remote is “pointer” to a peer repo at some URL, identified by a nickname. The familiar “origin” is the default nickname of the remote you cloned from.
q[ git remote -v ] shows the URL and nickname of each remote.
I plan to use bighub branches for backup:
Note:
git rev-parse –abbrev-ref HEAD
–to recreate current feature branch br2 as a clone of br3
The slower method is ” git checkout br3; git branch -d br2; git checkout -b br2″
The slightly faster method is “git reset –hard br3”
–Most git commands accept –help
On your Stash page change base branch to the target branch (say BB) -> click on the “…” dropdown -> choose “Create a branch from here” -> specify new name (say NN) -> delete branch BB.
Navigate to the page of your chosen commit (such as this sample page), then find the link on the top right “Tag this commit”
git show your_tag # look into one tag
The Stash page below also helps, provided the tag is published on Stash.
… shows all tags, including the commit and the annotation. Choose one you want to edit and go to Actions column click the 3 dots and choose Edit.
It might be due to the networked file system. We’ve found that doing the following might speed it up:
git config --global core.preloadindex True |
See stackoverflow for details.
FILENAME=<myfile> git log --all --format=%H $FILENAME | while read f; do git branch --contains $f; done | sort -u |
First remove it from Stash. Easy and safe to do on Stash web site. Go to the page listing all mod branches. Locate your branch you don’t want. Click on the “…” on the far right, to show the dropdown and find “Delete”. This would complete the deletion on the central repo. Next in your local repo, run
git fetch --prune |
This command would sync up the local repo to match central repo on Stash. The deleted branch will now be deleted locally. Without this step, git branch -a would forever show the obsolete branch.
Remember each local repo or central repo holds a copy of all the branches. Deleting branch123 from one repo doesn’t automatically delete branch123 from another repo. Similarly, adding branch321 to one repo doesn’t automatically add branch321 to another repo.
If possible, we use the Stash interface to merge. The resulting commit message on Develop branch looks like
Sometimes we get a conflict when merging the PR. For example, PR #153 has one file modified in the incoming branch release/0142c. Same file was very recently modified on Develop. Therefore this file had 2 concurrent changes, resulting in a merge conflict. This is what Victor did to resolve it, not necessarily optimal or recommended.
git fetch origin release/0142c git branch -d develop git checkout develop # check out latest from Stash git merge FETCH_HEAD # one file in conflict, to be resolved cd models/PyQXLModelsLib/ddl/ vi PyQXLModels_ddl_pycxx.cfg git diff origin/develop PyQXLModels_ddl_pycxx.cfg # ensure the diff is exactly what we expect git add PyQXLModels_ddl_pycxx.cfg git commit # see the comment message below git log --simplify-merges # verify git push origin HEAD # may need special permission to push Develop to Stash |
Here’s the commit message I used in the merge commit:
Merge pull request #153 manually from release/0142c to develop
[CFMQUANT-235] resolve minor conflict on one file
Another option for a visual interface for git under Windows is TortoiseGit. This isn’t a GUI, as such, but a shell that sits on top of Windows Explorer. Some people like it for this reason; some people dislike it for this reason.
It gives a convenient way to see the status of your files, and a convenient way (right-clicking) to select most commonly-used git commands (you can of course still use the command line whenever that is more convenient). There is some pain involved in setting up the key for connecting to the server – scroll down to ‘Interface’ and ‘Commands’ below to see if you think the gain is worth the pain.
Git command line is rather rich and powerful, featuring hundreds (possibly thousands:) of commands + sub-commands + combinations of switches to those commands. (https://www.kernel.org/pub/software/scm/git/docs/ lists more than 100 top-level commands). It’s impractical for any GUI tool to emulate the command line. Tortoise provides a good information-radiator tool, that saves you lots of repetitive typing.
Convenience is where Tortise distinguishes itself from other software tools.
In WinExplorer, Tortise lets you right click any modified file (or multiple files) to commit to your local branch. After the commit, the dialog screen lets you push to the central branch on Stash.
Similarly, if you have a new file to commit, you can right click and add, then commit.
You can also right click and diff with previous version.
TortoiseGit is free, and can be downloaded from http://tortoisegit.org/download/ You’ll need to download the 64 bit version, and then run it (it will prompt for an x account password during the installation). It does try to restart a lot of programs (so make sure you’ve saved everything), but doesn’t require a restart. The default options in the install wizard worked fine for me.
For some reason, TortoiseGit only accepts keys in putty key format, so the key that works with Git needs to be converted to this different form (this should be a once-off). An explanation of how is given here: http://develop-for-fun.blogspot.com.au/2013/12/configure-tortoise-git.html (basically you need to download puttygen.exe to convert the format of the key).
To create a new repository based on the stash repository, you can use Windows Explorer to create a new folder, move into that folder and then right click, and choose “Git Clone…” to bring up a dialog box.
Set the url to ssh://git@….. the directory to where you want it installed. You’ll need to click on “Load Putty Key” and put the address of the putty key saved down from puttygen earlier, which could be any stable folder in your C: drive. Avoid moving this folder.
Once successfully installed, Windows Explorer in folders associated with a workspace will now look something like
A full list of icons is given at https://tortoisegit.org/docs/tortoisegit/tgit-dug.html#tgit-dug-general-dia-icons
Right clicking on a file or folder brings up a menu of git commands. Right clicking at the top of the directory tree means you can commit all changes, or click on merge to bring up a GUI interface to merge everything.
The full manual can be found at https://tortoisegit.org/docs/tortoisegit/
If you are using a workspace that you set up outside of TortoiseGit (e.g. via the command line), then before you push to, or pull from, the server, you will need to point TortoiseGit to the putty key, by selecting TortoiseGit->Settings, then under “Git”, select “Remote”, then click on “origin” in the “Remote” box, and then set Putty Key.
Victor had to fix his registry to get Windows Explorer to show the (nice little) icons. In addition to http://martinbuberl.com/blog/tortoisegit-icons-not-showing-workaround/ , he had to kill all Explorer.exe processes in taskmgr before relaunching Explorer.
Explorer “overlay” (technical jargon) is no mature and stable technology. Victor estimates a few times a year the icons would disappear on (subset of) the version-controlled files, often for no obvious reason, and then reappear at a random time. In spite of frequent disappointments, many users love these little icons.
beyond-compare… I haven’t configured it successfully.
–Pandoc
I added this chunk into my .gitconfig file:
[diff "pandoc"]
textconv=pandoc --to=markdown
prompt = false
[alias]
wdiff = diff --word-diff=color --unified=1
Three trees are 1) workTree 2)staging i.e. Index 3)HEAD i.e. the current branch
https://www.atlassian.com/git/tutorials/undoing-changes/git-reset is my first and most memorable introduction on the three trees of git, in the context of git-reset.
—– A (code) change can be in three states or statuses (https://git-scm.com/book/en/v2/Getting-Started-What-is-Git%3F)
To transform an unstaged change to a staged change, you use git-add. For an entire file (rather than a code change), you “mark” it as staged using git-rm, git-mv or git-add. Some “undercover” operations also put a change into staging. So git-diff won’t show it, but git-diff-HEAD would.
To transform unstaged or staged change to a committed change, you use git-commit
I often forget a change is in staged-uncommitted. The bare git-diff won’t reveal it.
—- paint analog
A code change is like a color paint. We paint new color on tree1, tree2, then tree3.
git-reset-mixed — rollback the paint from tree3 then from tree2, leaving the new paint only on tree1 i.e. workTree. In contrast, git-reset-hard is removing the paint in all 3 trees
git-diff compares tree1 vs tree2.
—- git reset is the main focus of this blogpost
In general, a particular (code)change goes through two transitions between the three “trees”:
To undo uncommitted (either unstaged or staged) changes, git-reset comes in three strengths:
Note the “soft” strength is irrelevant to our goal. Only used to undo a commit, to rollback to an earlier commit.
—-git diff
http://blog.osteele.com/2008/05/my-git-workflow/ has a nice flow chart:
$ git diff HEAD # compares workTree vs HEAD
$ git diff – -staged # compares staging vs HEAD, only needed to investigate the (mysterious) staging
$ git diff # by default compares workTree vs staging, but won’t show new files added to staging 😦
Q: How do you remember the last (unsticky) point?
A: Recall that when you do a git-add on an updated file, your update gets copied from workTree into staging. Thereafter the change is no longer flagged by the bare git-diff which compares workTree vs staging.
I had a strange problem
To investigate, I ran
I now think the problem was — I have a dir named ‘rb3’ !
http://www.paulboxley.com/blog/2011/06/git-caret-and-tilde has good examples
HEAD~1 and HEAD^1 are probably identical, but not ~2 vs ^2
^ looks like a family tree branching point, signifying multiple parents for each child node.
If you want the branch to show up in Stash, then it is probably simpler to create it on Stash website (choose the correct parent branch …). After that
git fetch # no arg after "fetch" ... will show the new branch downloaded to local repository as "remote branch" git branch -a # list all (local and remote) branches git checkout feature/new_br_from_stash # creates a matching local branch |
git branch feature/my_br # creates a brand-new branch named feature/my_br, in the local repo only. git branch # lists all available branches in local repo git checkout feature/my_br # selects my_br as the default branch. git branch -m feature/my_BR # renames the default branch to feature/my_BR, in the local repo only. git push origin feature/my_BR # creates and copies branch to Stash, assuming branch doesn't exist there. |
(Note Git branches are designed to be disposable. So in theory you could create a branch for a small change and then merge and throw it away. No best practice no recommendatation yet.)
All feature branches, including temporary throw-away branches, can be deleted from Stash.
Branching is different in git vs svn/cvs. By itself git branching isn’t too complex.
The git local/remote set-up is new to me. By itself, not too complex.
However, in reality we have to manage the combination of branching and sync – a higher level of complexity addressed in many online discussions. I would prefer to rely on the git commands (rather than GUI tools or Stash) to understand and manage it.
I like the philosophy in http://longair.net/blog/2009/04/16/git-fetch-and-merge/
–comparing the local branch vs remote branch
git diff feature/my_br6 origin/feature/my_br6 — path/to/your/file
–to see the mapping between local ^ remote branches
git branch -vv
— FETCH_HEAD:
http://stackoverflow.com/questions/1800783/compare-local-git-branch-with-remote-branch
–check out a remote branch? local branch to track remote branch?
http://makandracards.com/makandra/521-check-out-a-remote-branch-in-git
http://stackoverflow.com/questions/1783405/checkout-remote-git-branch
–delete a branch locally, then remotely:
http://gitready.com/beginner/2009/02/02/push-and-delete-branches.html
git fetch origin master:master
You can show in a window a list of all files modified locally but uncommitted. You can then double-click each file to pop-up a diff screen, such as BeyondCompare. You can click to select one or more of these files to commit. For me this is the most convenient way to keep track of a large number of code changes. Same feature exists in TortiseSVN.
You can limit the scope to one directory (AgModels for eg). Within the same screen, you get a checkbox to widen the scope to entire repo.
There’s another checkbox to include unversioned (i.e. newly created) files. You can then add them to git with very few clicks.