In January 2024 I followed this approach with good results:
$ git submodule add <url> <path> $ git submodule absorbgitdirs <path>
source (Julia Evans blog)
PDF version
This answer is very deep; in my case I only used the first incantation:
git reset --soft HEAD@{1}… but not the second one:
git commit -C HEAD@{1}Instead, I typed the commit message anew. Note, in particular the answer's caveat that HEAD@{1} is pointing to different things in the two incantations. Like I said, pretty deep.
git stash pop // manually resolve conflicts and save the files (NB: don't use "git add" !!) git restore --staged . git stash drop
These are the contents of the ~/.giconfig file on my Ubuntu 20.04 ThinkStation machine as of November 2022:
[core] excludesfile = /home/mperdikeas/.gitignore_global editor = emacs [alias] lgb = log --color --graph --pretty=format:'%C(yellow)%h%Creset -%C(bold red)%d%Creset %s %Cgreen(%cr) %C(bold blue)%Creset' --abbrev-commit lg = log --color --graph --oneline --decorate sstatus = status -s --ignored ppush = "!sh -c 'git push --all && git push --tags'" df = difftool branchdate = !git for-each-ref --sort='-authordate' --format='%(refname)%09%(authordate)' refs/heads | sed -e 's-refs/heads/--' [color] ui = true diff=always status=auto branch=auto [diff] tool = vimdiff external = git-meld [user] name = mperdikeas email = mperdikeas@gmail.com [push] default = current [credential] username = mperdikeas@gmail.com password=ghp_kdflk328DtBTa3KvS_obviously-mangled # I've put the PAT here, obviously mangled helper = store [gc] auto = 0
I followed the below workflow recently:
git fetch origin pull/7/head:pr7 git checkout -t -b origin_master origin/master git merge pr7 git push origin HEAD:master
Following the above I also did:
git checkout -B master origin/master… whereupon I got the following message:
Branch master set up to track remote branch master from origin. Switched to and reset branch 'master' Your branch is up-to-date with 'origin/master'.
This is supposedly useful when I also have commits in my local repo that I haven't pushed for a while while the collaborator has pushed his commits to github. Rebase also results in a linear history in contrast to merge. That was the theory at least; I tried that circa September 2020 and it didn't work too well …
$ git fetch -v $ git pull --rebase origin master
NB: there should be no slash between origin and master
So failing the above I had to resort to the familiar:
git fetch -v git merge origin/master
In both cases you obviously still have to deal with the merge conflicts.a
To edit the checked-out branch's description:
git branch --edit-description
To view a branch's (say awesome-new-feature) description:
git config branch.awesome-new-feature.description
git branch
command doesn't display the branch description:
git branch -vv
git log --follow -- path/to/file
In a recent rebase operation (where I was following the script given here), I had the following output:
$ git rebase master First, rewinding head to replay your work on top of it... Applying: < some commit message > Applying: < some commit message > Applying: < some commit message > Applying: < some commit message > Using index info to reconstruct a base tree... Mdocs/release-notes .git/rebase-apply/patch:46: trailing whitespace. warning: 1 line adds whitespace errors. Falling back to patching base and 3-way merge... Auto-merging docs/release-notes CONFLICT (content): Merge conflict in docs/release-notes error: Failed to merge in the changes. Patch failed at < some commit message > The copy of the patch that failed is found in: .git/rebase-apply/patch When you have resolved this problem, run "git rebase --continue". If you prefer to skip this patch, run "git rebase --skip" instead. To check out the original branch and stop rebasing, run "git rebase --abort".
Following the advice given in the linked source I did the following:
docs/release-notes
)git add
the edited files. NB: be sure to not commit
at this point, no commit
is necessarygit rebase --continue
as that was the command Git said to do when you completed.git diff-tree --no-commit-id --name-only -r bd61ad98
$ git checkout 855f48bd39cf56ef3ddb94389243ebd3e5b0bb8f ../../path/to/file $ echo 'do your tests' $ git reset --hard $ echo 'you are now back where you started (before the checkout)
If the "other" branch is "master" you can do a:
git merge-base HEAD master(the operation is obviously commutative)
The following can also serve to graphically show the branch point:
git log --graph --oneline --all
git stash save -u
$ git diff --name-status commit-id-1..commit-id-2Notes:
git diff --name-status fc847cb^..fc847cb.. shows all the changes made between the ancestor of commit git fc847cb and commit fc847cb. I.e. all the changes made in that particular commit only. E.g. if you see the following:
$ git diff --name-status fc847cb^..fc847cb M FileA.java M FileB.java M FileC.java… it means that the above three files were modified (M) in that particular commit.
Based on the example above, to see the changes made in FileB.java in the commit fc847cb (only) you can do:
git diff fc847cb^:FileA.java fc847cb:FileA.javaThe above says: show me the differences of FileA.java between the direct ancestor of commit fc847cb and commit fc847cb. I.e. the differences in FileA.java made in commit fc847cb.
To see the changes of a particular file over a number of commits you just provide the range of the two commits (beginning commit and ending commit). E.g. to see how file FileA.java changed between commits 12347dd and fc847cb do:
git diff 12347dd:FileA.java fc847cb:FileA.javaAlternatively, the following also works:
git diff 12347dd fc847cb -- FileA.javaInstead of commit numbers you may use HEAD (for the tip of the current branch) or a branch name (in which case the tip of that branch is used)
To see all changes (including unstaged ones):
git diff --no-ext-diff 968da4d -- path/to/file
To see only up to staged changes:
git diff --no-ext-diff --staged 968da4d -- path/to/fileNotice that in the above it is an error to give HEAD after the --staged as HEAD is implicit.
To see up to the tip of the current branch:
git diff --no-ext-diff 968da4d HEAD -- path/to/file
Based on this and this, I am now resolved to using the following workflow:
E.g.
$ git checkout -b cool-feature $ git rebase master $ git checkout master $ git merge cool-feature $ git branch -d cool-featureNote that git will bark at the branch delete command if it thinks it's not fully merged so no worries.
Say you branched off from master at some point in the past and you are now in a branch for a cool new feature. Given that in the meantime (i.e. since you branched-off) the master branch has also advanced doing (from your feature branch) the following:
git diff --name-only master… will also show files changed in master.
To actually only see differences since the point you branched off from master (and not to bother with subsequent master commits), you need to do (from your feature branch):
git diff --name-only master...Note that there is no space between master and ...
git stash -k -u git checkout -b new-branch git stash pop git commit -m 'applied stashed changes in new branch' git stash drop
This will stash all modifications that you did not git add:
git stash -k
Note that newly created (and non-added) files will remain in your working directory unless you also use the -u switch.
git stash -k -uAlso, your working directory must be clean (i.e. all changes need to be added) when you git stash pop later on.
Assuming you've cloned your repository with git clone --recursive (which you always should), then do a:
git submodule update --recursive --remote
Then,
git submodule update --recursive --remote
prior to fetching
and merging the top-level repository.git log --diff-filter=D --summary | grep delete | grep -i file-name-fragment
git log -1 --stat -- full-path-to-the-file
git checkout commit-identifier^ full-path-to-file
The gist of the idea is to create an orphan gh-pages branch which will include only the HTML pages you wish to publish, and then push it to the origin:
git checkout --orphan gh-pages
git symbolic-ref HEAD
git add . -A
git commit -m 'gh-pages initial'
git push -u origin gh-pages
git checkout master
… following the above steps it may take a couple of minutes before your site
becomes visible in:
https://<your-github-id>.github.io/<repository-name>/dir/to/some/index.html
git rm the_submodule rm -rf .git/modules/the_submodule
git submodule add https://github.com/fxbois/web-mode.git .emacs.d/web-modeThe last argument is the path in which the submodule should reside. NB: obviously people that have already cloned the repo (prior to the addition of the submodule) would still have to do:
git submodule update --init --recursiveOtherwise (i.e. if the cloning happens after the addition of the submodule it is better to just do:
git clone --recursive git://github.com/some/repo.git(see how to clone a repo including the submodules).
$ git config --global credential.helper 'cache --timeout=3600' # Set the cache to timeout after 1 hour (setting is in seconds)source
sudo apt-get install tigE.g. to view history on single file:
tig [filename]
git reset --hard HEAD~1source.
git diff-tree -r df7fc29long and clean:
git diff-tree --no-commit-id --name-only -r df7fc29- consumed in my git-show-files script (in ~/tools)
cd && git clone https://github.com/mperdikeas/dummy.git
cd dummy && echo "foo" >> foo && git add . -A git commit -m "foo added" && git push
cd ~/svn-playground/ && svnadmin create svn-server/dummy/
cd ~/svn-playground && mkdir dummy-client && cd dummy-client svn co file:///home/mperdikeas/svn-playground/svn-server/dummy . svn mkdir trunk && svn commit -m 'created trunk directory'
~/dummy/.git/config
file:
[svn-remote "svn"] url = file:///home/mperdikeas/svn-playground/svn-server/dummy/trunk fetch = :refs/remotes/git-svn
cd ~/dummy/ && git svn fetch svn git checkout -b svn git-svn
git merge master git svn dcommit
cd ~/svn-playground/dummy-client/ && svn update(files 'foo' and 'README.md' should now be present in the dummy-client (in the trunk repository). working copy
cd ~/dummy && git checkout master git rebase svn && git branch -d svn
cd ~/dummy git status git branch
echo "zoo" >> zoo && rm foo && git add -A && git commit -m "zoo added, foo removed" & git push
cd ~/svn-playground/dummy-client/ && svn update(nothing should be added)
cd ~/dummy && git svn dcommit
cd ~/svn-playground/dummy-client/ && svn update
svn co http://svn.example.com/foo cd myproj svn mkdir trunk svn commit -m 'Created trunk directory'Once this is done, you can throw away the directory you checked out of subversion.
In our case, we have a central repository running on a local installation of Gitorious. This is a bare repository, which makes things a little tricker, as git-svn requires a working copy. To get round this, we create a clone, which we’ll use as an intermediate step in the mirroring process. If you're not mirroring a bare repository, you can omit this step.
The repositories we want to mirror are in ~git/repositories, and we’ve created a directory ~git/repositories/svn-mirror where we'll put the clones. For this example, we'll use a repository called foo/mainline.git.
Create the clone:
git clone ~git/repositories/foo/mainline.git ~git/repositories/svn-mirror/foo cd ~git/repositories/svn-mirror/fooNow add the following to .git/config (with the correct svn URI, of course):
[svn-remote "svn"] url = http://svn.example.com/foo/trunk fetch = :refs/remotes/git-svnNow do an initial fetch of the empty subversion remote, and check it out as a new git branch (called svn):
git svn fetch svn git checkout -b svn git-svnYou can now merge in all your commits from master, and push them to subversion. You’ll probably want to go and make a coffee or something while the dcommit runs – if you haven’t used subversion for a while you’ve probably forgotten just how much slower it is than git.
git merge master git svn dcommitTo allow pushing to svn from master, rebase master to the svn branch (which can then be deleted):
git checkout master git rebase svn git branch -d svnAt this point you should be able to manually update subversion at any time by running git svn dcommit from the master branch.
$ git log -1 # note the SHA-1 of latest commit $ git checkout master # reset your branch head to your previously detached commit $ git reset --hard [commit-id]
git tag -l
git checkout origin/HEAD
git ls-remote --tags
git format-patch 3266a7e(in the above example all changes between identified commit and the tip of the branch will be reported)
git diff 3266a7e 8deaaf2 > ~/lastchanges.patchThe git-format-patch method produces cleaner output.
find . ! -type d ! -iname nosecurity_mvn.zip -exec echo git add {} \;
git ls-tree
or..
git-ls-tree
This, and many other commands are available at /usr/lib/git-core
git tag -l -n1
git stash git reset --hard git clean -xf git clean -df git branch newBranch git checkout newBranch git stash pop git add . -A -n git commit -m "first commit on new branch"
git commit --amend -m "New commit message"
git log --oneline --decorate=full --graph
git submodule init git submodule updateApparently git submodule update --init --recursive is also an option. See for more: how to clone a repo including the submodules).
git rev-parse --verify HEAD
- or simply -
git rev-parse HEAD
git checkout -f visualization "13 - COAST Caches/ccaches_protocol_types/src/org/coast/caches/network/types/CacheGetRequest.java"In the incantation above 'visualization' (i.e. the branch name) is a tree-ish object in git. The general signature of git checkout is therefore:
git checkout
git checkout .
$ git clean -d -x -f $ git reset --hardto just see which files will be deleted by git clean do a dry-run:
$ git clean -d -x -n
$ git diff master origin/master
git add . -A git commit -m " .. "do a:
git config --global alias.ac '!git add . -A && git commit'
git config --global color.diff auto
git reset --hard HEAD~1The HEAD~1 means the commit before head. Or, you could look at the output of git log, find the commit id of the commit you want to back up to, and then do this:
git reset --hardIf you already pushed it, you will need to do a force push to get rid of it...
git push origin HEAD --forceHowever, if others may have pulled it, then you would be better off starting a new branch. Because when they pull, it will just merge it into their work, and you will get it pushed back up again. If you already pushed, it may be better to use git revert, to create a "mirror image" commit that will undo the changes. However, both commits will both be in the log. FYI -- git reset --hard HEAD is great if you want to get rid of WORK IN PROGRESS. It will reset you back to the most recent commit, and erase all the changes in your working tree and index. Lastly, if you need to find a commit that you "deleted", it is typically present in git reflog unless you have garbage collected your repository. comment: HEAD~1 or just HEAD^. If you pushed, you should use git revert instead