简体   繁体   中英

Git. svn dcommit analog for git repos

I want to use next typical workflow:

  1. create new branch for feature, and checkout it
  2. do commits in feature branch
  3. checkout master
  4. merge with feature branch.
  5. push changes

It is very typical use case. However, there is one thing that anoying me - I dont want to show my branch commits to public. I just want to push only merge commit, without feature developing history.

One can propose to use git rebase with commits squashing. But in fact, such squashing is just workaround, not a real solution. I want to have all my commits localy, merge graph, for history purposes.

I want to get simmilar that I get with git svn dcommit - only merge commit is pushed onto the remote, but I see localy whole history of development, with feature commits, with two-parents merge node and appropriate merge graph.

You could try

git merge --squash <feature branch>

That will do everything you want with the exception of the branch's not actually being considered merged.

If I understand you correctly, you want to have one commit (ie one SHA1), but you want it to look differently on your copy of the repository than on on the central copy.

Doing that is just impossible. Git was made so that this way impossible. If you know a SHA1 id of a commit in a repository, you can be sure that you know all its history.

But, there is one way to fake that: using grafts . This way, you can add a parent to a commit without actually modifying it. Although I'm not really sure this is a good idea.

Based on your comments, here's another solution: Do your work in feature branches, like normal. Merge feature branches into master as needed, like normal. Before you push to the remote, do a squash merge to a separate branch, and push that branch to the remote. Example:

# Create two repos for testing
mkdir test-git-merging
mkdir test-git-merging2
cd test-git-merging2
git init
# Have to set this flag to be able to push with master checked out
git config receive.denyCurrentBranch ignore
cd ../test-git-merging
git init
# Base commit in first repo
git commit --allow-empty -m "init"
# Create the branch that will be pushed to the remote
git branch remote-master
# Make some files and commit them in master
echo foo >> foo
echo bar >> bar
git add .
git commit -m "added files"
# Make a change on a branch
git checkout -b branch
echo 1 >> foo
git commit -am "Modified foo"
# Make a non-conflicting change in master
git checkout master
echo 2 >> bar
git commit -am "Modified bar"
# Do a normal merge from branch to master--normal history
git merge branch
# Squash merge from master to special remote branch
git checkout remote-master
git merge --squash master
git commit -m "Everything is squashed"
# Set up the remote and push config
git remote add other ../test-git-merging2
git config branch.remote-master.remote other
git config branch.remote-master.merge master
git config push.default tracking
# Push the branch
git push

I've tested that sequence of commands to see that it works. Of course, the branch remote-master will still never have real history, meaning that it will always be dangerous to pull stuff back from it to your working branches, but that's essentially what you're asking for.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM