What's the equivalent of hg pull and merge in git -
coming mercurial, i'm struggling bit terminology , methods git. here's current situation:
both servers share same repository.
- on server 1 developer committed change file.php.
- on server 2 developer committed change file.php. same change, different commit.
i need bring these changesets in sync
to resolve in mercurial, run 3 commands below server 2. merge conflicts resolved in editor or meld.
hg pull -u ssh://remote-server1//shared-repository hg merge hg commit -m "branch merge" how do git?
what i've done
using https://www.mercurial-scm.org/wiki/gitconcepts guide, attempted git pull fails since have not run git config. repository in production , shared many, i'm trying avoid setting username.
following https://stackoverflow.com/a/17713604/456645, ran command:
git fetch ssh://remote-server1//shared-repository it responds
from ssh://remote-server1//shared-repository * branch head -> fetch_head i have yet figure out how run git reset in situation.
git reset ssh://remote-server1//shared-repository/master # fails (fatal: invalid object name 'ssh'.) git reset origin/master # fails (fatal: ambiguous argument 'origin/master': unknown revision or path not in working tree.) git reset fetch_head/master # fails (fatal: ambiguous argument 'fetch_head/master': unknown revision or path not in working tree.) looking further, i'm confused find single branch
git branch -a * master just sure wasn't auto-merged, check history
git log -n 3 # here, find changesets existed. nothing new at point, don't know happens git fetch. see no evidence of fetch.
tl;dr version
add remote each repository. i'll call 2 repositories alex , bob, should choose more appropriate names. note if git clone 1 of them, 1 have name origin automatically (although can choose name). below assumes have related repository, , need add both, if have origin need add other one.
$ git remote add alex ssh://their.domain.name/their/path/to/repo.git $ git remote add bob ssh://bobs.domain.name/and/his/path.git after can git fetch (all branches, etc) them:
$ git fetch alex $ git fetch bob you have "remote tracking branches" named alex/master, alex/develop, etc., wherever alex has branches named master, develop, etc.; , have bob/master , on wherever bob has master.
now if wish merge stuff, can make own local branch(es) corresponding 1 of theirs:
$ git checkout -b alex-master alex/master (alex-master local branch; call master if prefer, each local branch name must unique, might have move own existing master out of way first) , merge bob's:
$ git merge bob/master (this merges bob/master local alex-master). if have permission can push result alex's master:
$ git push alex alex-master:master and bob's master:
$ git push bob alex-master:master the "refspec" given last argument git push takes local branch name on left hand side of colon, , local branch name on right.
unlike mercurial, there no special branch name; master conventional, while in hg, default bit magic. (well, there's 1 special magic bit master in git: changes way git merge spells default commit message. that's it.)
there bunch of parts this, of cosmetic/convenience, , of crucial.
first, in git these days 1 refers repositories through "remotes". remote partly convenience construct plays crucial bits, in terms of obtaining , retaining commits repository.
mercurial has simpler remotes, serves part of convenience: in [paths] section in .hgrc file can list long url under short name:
[paths] short = ssh://something.very.long/with/a/very/long/path/that/is/a/pain/to/type/every/time or whatever. compare git "remote", in .git/config:
[remote "short"] url = ssh://something.very.long/with/a/very/long/path/etc so far these same, different spellings/syntax. there's bit:
fetch = +refs/heads/*:refs/remotes/short/* (in fact, appears before url order of these 2 not matter). we'll in bit.
next, direct equivalent of hg pull indeed git fetch. however, hg pull has -u, git fetch not do, because internals of 2 operations wind being quite different because of difference between mercurial branch , git branch.
a mercurial branch sort of "real thing", while git branch more ephemeral. more / precisely, git branch more mercurial bookmark mercurial branch. however, there's concept (or maybe "conceit" might better word) not translate here: specifically, commits added mercurial repository numbered sequentially , remain in repository if nothing names them: wind anonymous head. instance can have commit graph (shown hg log --graph etc) looks like:
o | o o | | o o / |/ o there not need external name pointing these 2 heads; they're anonymous heads (within branch since commits in hg within branch definition).
in git, contrast, commit no external name eligible garbage-collected (what hg might call "stripped", although details differ). of hg calls "heads" must have kind of name. remote's fetch = line comes effect.
"but wait," might ask, "i can git fetch ssh://... , has no named remote!" head -> fetch_head bit comes in.
if don't have "remote", can still bring in branch (or more one) repository. however, heads of branches obtained need name. "name" stuffed pseudo-branch named fetch_head. details complicated, if bring on single branch, in case, it's easier explain , think-about: essentially, git brings on 1 named branch and, in local repository, gives name fetch_head.
note subsequent git fetch overwrites fetch_head, @ point commits brought on eligible garbage-collection. thus, need step, once have commits.
now, once have commits , want retain them, there different ways this. hg pull-like use "remote" mechanism. here, fetch = line takes care of problem. when git fetch remote, remote has branch names pointing branch heads (by definition since git requires this). these branch names references of form refs/heads/name.
the fetch = line tells git how rename branches have new, unique local names in local repository. renaming refs/heads/master refs/remotes/short/master, instance, short/master new local name remote called "branch master". retains commits , we're (though still have merge).
alternatively, can 1 interesting branch on , call fetch_head , merge. when this, pick local branch (e.g., master), check out if needed, , run git merge fetch_head.
once merge done, have our local branch (master, in example) pointing, perhaps through merge commit, commits brought on via git fetch, no longer vulnerable garbage-collection: on branch, hence name-able via branch name. can safely overwrite fetch_head time.
this last method—bringing stuff on naming fetch_head, merging local branch fetch_head—is "git pull" command does. in sense, it's git fetch followed git merge. try avoid pull script has lot of magic handle various corner cases, in old days go awry in un-considered corner cases; , in general prefer fetch, on happened, , choose whether , how merge or rebase own code.
ultimately there's no single right way, if going more once, add git remote, , use "remote branch" notion (the fetch = stuff renames "their" branches own locally-stored "remote-tracking branches").
Comments
Post a Comment