I want my new branch to have only commit0 that is the code of the last state (commit3), with no previous history.
You can get this pretty easily:
git checkout commit3 # get index and work-tree set up
git status # make sure you're on commit3 and things are otherwise clean
then:
git checkout --orphan new-branch
git commit
and you have this new commit0
on a new branch, with no history behind it: commit0
is a new root commit.
I wish then to merge stuff easily for example if I do commit4 in my local branch, I wish to have only commit0 and commit4 changes in the remote branch.
You cannot get this at all. You can set things up so that you have commit0 and then commit5, where commit5's snapshot matches commit4's snapshot and has commit0 as its parent. But commit4—the commit with that hash ID—has commit3 as its parent, forever. Hash IDs are universal across all Git repositories, and no part of any commit can ever be changed, including its parent linkage.
It's important to realize that the word branch, in Git, is ambiguous: see What exactly do we mean by "branch"? Sometimes branch means chain of commits, terminated by one specific commit. Sometimes it means branch name. Git repositories all have their own private branch names, so there's no reason that master
in the Git repository reachable at URL $url1
has to name the same commit that master
in the Git repository at $url2
names.
The histories, however, are the commits. Merge works by using the history. If two chains-of-commits don't connect, there is nothing to merge.
Git does allow you to build your own solutions: it's a tool-set, not a solution in itself. You could write your own Git commands that let you add a new snapshot to a branch name of your choice, without using any of the existing commits in your actual working branches. This might let you build the device you want:
git my-private-copy-to new-branch <commit-specifier>
would run your git-my-private-copy-to
command, which would add a new commit using a tree (from argument 2) to the specified branch (argument 1). Note that in the command I'm imagining—which does not exist but would just be a small shell script—there is no merging involved.
Since the command does not exist and you must write it, if you would like merging, you can put that in the command you write—but a standard merge uses, and adds to, the history recorded in the commit graph or subgraph, and you've deliberately made sure that your main work and this new-branch
subgraph are disjoint subgraphs.