mirror of
https://github.com/pcottle/learnGitBranching.git
synced 2025-07-09 06:04:26 +02:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
8af0788bb4
17 changed files with 417 additions and 36 deletions
1
CNAME
Normal file
1
CNAME
Normal file
|
@ -0,0 +1 @@
|
|||
learnGitBranching.js.org
|
|
@ -118,6 +118,7 @@ And the following heroes for assisting in translating:
|
|||
* Eroany H Leader ("lhyqy5")
|
||||
* Honorat ("ahonorat")
|
||||
* Vasil Kulakov ("coyl") & Lyubov Agadjanyan ("shayenblue")
|
||||
* Aliaksei Berkau ("alexeiberkov")
|
||||
|
||||
Also huge shoutout for everyone who has put up a pull request that was pulled! Check out the 30+ contributors we have in the [Contributors View](https://github.com/pcottle/learnGitBranching/graphs/contributors)
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
"react-tools": "^0.13.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"backbone": "^1.1.2",
|
||||
"backbone": "~1.1.2",
|
||||
"events": "^1.0.2",
|
||||
"flux": "^2.0.1",
|
||||
"jquery": "~1.7.3",
|
||||
|
|
|
@ -84,7 +84,7 @@ var expectTreeAsync = function(command, expectedJSON, startJSON) {
|
|||
console.log(JSON.stringify(getHeadlessSummary(headless)));
|
||||
}
|
||||
return compareAnswer(headless, expectedJSON);
|
||||
}, 'trees should be equal', 100);
|
||||
}, 'trees should be equal', 400);
|
||||
};
|
||||
|
||||
var expectLevelSolved = function(levelBlob) {
|
||||
|
|
|
@ -378,7 +378,9 @@ exports.strings = {
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
'git-warning-hard': {
|
||||
'__desc__': 'One of the warning messages for git',
|
||||
'en_US': 'The default behavior is a --hard reset, feel free to omit that option!',
|
||||
'en_US': 'The default behavior for resets on LearnGitBranching is a --hard, so feel free to omit ' +
|
||||
'that option if you get tired of typing it out in our lessons. Just remember that the default ' +
|
||||
'behavior on actual Git is --mixed.',
|
||||
'de_DE': 'Das Standardverhalten in dieser Demo ist --hard, du kannst die Option auch weglassen!',
|
||||
'zh_CN': '默认的行为是 --hard 硬重置,尽管省略掉那个选项吧!',
|
||||
'zh_TW': '預設的行為是 --hard reset,儘量省略掉那個選項吧!',
|
||||
|
|
|
@ -21,7 +21,6 @@ var MultiView = require('../views/multiView').MultiView;
|
|||
var CanvasTerminalHolder = require('../views').CanvasTerminalHolder;
|
||||
var ConfirmCancelTerminal = require('../views').ConfirmCancelTerminal;
|
||||
var NextLevelConfirm = require('../views').NextLevelConfirm;
|
||||
var LevelToolbar = require('../views').LevelToolbar;
|
||||
|
||||
var MarkdownPresenter = require('../views/builderViews').MarkdownPresenter;
|
||||
var MultiViewBuilder = require('../views/builderViews').MultiViewBuilder;
|
||||
|
@ -45,6 +44,7 @@ var LevelBuilder = Level.extend({
|
|||
initialize: function(options) {
|
||||
options = options || {};
|
||||
options.level = {};
|
||||
this.options = options;
|
||||
|
||||
var locale = LocaleStore.getLocale();
|
||||
options.level.startDialog = {};
|
||||
|
@ -75,10 +75,6 @@ var LevelBuilder = Level.extend({
|
|||
},
|
||||
|
||||
initName: function() {
|
||||
this.levelToolbar = new LevelToolbar({
|
||||
name: intl.str('level-builder'),
|
||||
parent: this
|
||||
});
|
||||
},
|
||||
|
||||
initGoalData: function() {
|
||||
|
@ -97,7 +93,6 @@ var LevelBuilder = Level.extend({
|
|||
this.doBothVis('hide');
|
||||
this.goalWindowPos = position;
|
||||
this.goalWindowSize = size;
|
||||
this.levelToolbar.$goalButton.text(intl.str('show-goal-button'));
|
||||
if ($('#goalPlaceholder').is(':visible')) {
|
||||
$('#goalPlaceholder').hide();
|
||||
this.mainVis.myResize();
|
||||
|
|
|
@ -71,7 +71,11 @@ var CommandView = React.createClass({
|
|||
<div id={this.props.id} className="reactCommandView">
|
||||
<p className={commandClass}>
|
||||
<span className="prompt">{'$'}</span>
|
||||
{' ' + this.state.rawStr}
|
||||
{' '}
|
||||
<span dangerouslySetInnerHTML={{
|
||||
__html: this.state.rawStr
|
||||
}}
|
||||
/>
|
||||
<span className="icons transitionAllSlow">
|
||||
<i className="icon-exclamation-sign"></i>
|
||||
<i className="icon-check-empty"></i>
|
||||
|
|
|
@ -75,7 +75,7 @@ var MarkdownGrabber = ContainedBase.extend({
|
|||
var confirmCancel = new Views.ConfirmCancelView({
|
||||
deferred: buttonDefer,
|
||||
destination: this.getDestination()
|
||||
}.bind(this));
|
||||
});
|
||||
}
|
||||
|
||||
this.updatePreview();
|
||||
|
|
|
@ -281,7 +281,6 @@ var LevelDropdownView = ContainedBase.extend({
|
|||
// also go find the series and update the about
|
||||
_.each(this.seriesViews, function(view) {
|
||||
if (view.levelIDs.indexOf(id) === -1) {
|
||||
view.resetAbout();
|
||||
return;
|
||||
}
|
||||
view.updateAboutForLevelID(id);
|
||||
|
@ -354,8 +353,7 @@ var SeriesView = BaseView.extend({
|
|||
template: _.template($('#series-view').html()),
|
||||
events: {
|
||||
'click div.levelIcon': 'click',
|
||||
'mouseenter div.levelIcon': 'enterIcon',
|
||||
'mouseleave div.levelIcon': 'leaveIcon'
|
||||
'mouseenter div.levelIcon': 'enterIcon'
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
|
@ -365,7 +363,11 @@ var SeriesView = BaseView.extend({
|
|||
this.levels = LevelStore.getLevelsInSequence(this.name);
|
||||
|
||||
this.levelIDs = [];
|
||||
var firstLevelInfo = null;
|
||||
_.each(this.levels, function(level) {
|
||||
if (firstLevelInfo === null) {
|
||||
firstLevelInfo = this.formatLevelAbout(level.id);
|
||||
}
|
||||
this.levelIDs.push(level.id);
|
||||
}, this);
|
||||
|
||||
|
@ -375,6 +377,7 @@ var SeriesView = BaseView.extend({
|
|||
this.JSON = {
|
||||
displayName: intl.getIntlKey(this.info, 'displayName'),
|
||||
about: intl.getIntlKey(this.info, 'about') || " ",
|
||||
levelInfo: firstLevelInfo,
|
||||
ids: this.levelIDs
|
||||
};
|
||||
|
||||
|
@ -396,13 +399,8 @@ var SeriesView = BaseView.extend({
|
|||
return $(element).attr('data-id');
|
||||
},
|
||||
|
||||
resetAbout: function() {
|
||||
this.$('p.about').text(intl.getIntlKey(this.info, 'about'))
|
||||
.css('font-style', 'inherit');
|
||||
},
|
||||
|
||||
setAbout: function(content) {
|
||||
this.$('p.about').text(content).css('font-style', 'italic');
|
||||
this.$('p.levelInfo').text(content);
|
||||
},
|
||||
|
||||
enterIcon: function(ev) {
|
||||
|
@ -411,12 +409,19 @@ var SeriesView = BaseView.extend({
|
|||
},
|
||||
|
||||
updateAboutForLevelID: function(id) {
|
||||
var level = LevelStore.getLevel(id);
|
||||
this.setAbout(intl.getName(level));
|
||||
this.setAbout(this.formatLevelAbout(id));
|
||||
},
|
||||
|
||||
leaveIcon: function() {
|
||||
this.resetAbout();
|
||||
formatLevelAbout: function(id) {
|
||||
var level = LevelStore.getLevel(id);
|
||||
return this.getLevelNumberFromID(id) +
|
||||
': ' +
|
||||
intl.getName(level);
|
||||
},
|
||||
|
||||
getLevelNumberFromID: function(id) {
|
||||
// hack -- parse out the level number from the ID
|
||||
return id.replace(/[^0-9]/g, '');
|
||||
},
|
||||
|
||||
click: function(ev) {
|
||||
|
|
|
@ -10,7 +10,8 @@ exports.level = {
|
|||
"es_AR": "Simulando el trabajo en equipo",
|
||||
"pt_BR": "Simulando trabalho em equipe",
|
||||
"zh_CN": "模拟团队合作",
|
||||
"zh_TW": "模擬團隊合作"
|
||||
"zh_TW": "模擬團隊合作",
|
||||
"ru_RU": "Коллективная работа"
|
||||
},
|
||||
"hint": {
|
||||
"en_US": "remember you can specify the number of commits to fake",
|
||||
|
@ -20,7 +21,8 @@ exports.level = {
|
|||
"es_AR": "Acordate que podés especificar cuántos commits simular",
|
||||
"pt_BR": "Lembre-se que você pode especificar quantos commits quer simular",
|
||||
"zh_CN": "记住为fake中的commit指定数量",
|
||||
"zh_TW": "你要記得指定要送多少個 commit 出去"
|
||||
"zh_TW": "你要記得指定要送多少個 commit 出去",
|
||||
"ru_RU": "помните, Вы можете указать колличество фейковых коммитов"
|
||||
},
|
||||
"startDialog": {
|
||||
"en_US": {
|
||||
|
@ -400,6 +402,60 @@ exports.level = {
|
|||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"ru_RU": {
|
||||
"childViews": [
|
||||
{
|
||||
"type": "ModalAlert",
|
||||
"options": {
|
||||
"markdowns": [
|
||||
"## Simulating collaboration",
|
||||
"",
|
||||
"В данном уроке мы находимся в немного затруднительном положении -- для выполнения ряда упражнений нам нужно обучить Вас как скачивать наработки и изменения, которые были сделаны в удалённом репозитории.",
|
||||
"",
|
||||
"Это означает, что нам следует \"сделать вид\", как будто мы знаем о том, что наш удалённый репозиторий, с которым мы работаем, был изменён наработками, сделанными одним из Ваших коллег / друзей / единомышленников. Это может быть какая-то ветка либо же какой-то конкретный коммит.",
|
||||
"",
|
||||
"Для того, чтобы добится своих целей, нам предоставляется комманда со звучным именем `git fakeTeamwork`! Имя комманды однозначно даёт понят что она выполняет. Давайте ознакомимся с демо..."
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "GitDemonstrationView",
|
||||
"options": {
|
||||
"beforeMarkdowns": [
|
||||
"Поведение комманды `fakeTeamwork` по-умолчанию заключаентся в том, чтобы просто \"инициировать\" коммит на master-е"
|
||||
],
|
||||
"afterMarkdowns": [
|
||||
"Ну вот -- удалённый репозиторый был изменён при помощи добавления нового коммита, и мы не ещё не скачали этот коммит, потому что не запустили комманду `git fetch`."
|
||||
],
|
||||
"command": "git fakeTeamwork",
|
||||
"beforeCommand": "git clone"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "GitDemonstrationView",
|
||||
"options": {
|
||||
"beforeMarkdowns": [
|
||||
"В данной комманде Вам доступна возможность указать ветку и колличество добавляемых коммитов"
|
||||
],
|
||||
"afterMarkdowns": [
|
||||
"С помощью одной лишь комманды мы симулируем добавление трёх коммитов в ветку `foo` на удалённом репозитории"
|
||||
],
|
||||
"command": "git fakeTeamwork foo 3",
|
||||
"beforeCommand": "git branch foo; git clone"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ModalAlert",
|
||||
"options": {
|
||||
"markdowns": [
|
||||
"Последующие уровни будут довольно сложными, поэтому в этом упражнении от Вас больше ничего не требуется.",
|
||||
"",
|
||||
"Вперёд! Склонируйте удалённый репозиторий (с помощью `git clone`), симулируйте какие-нибудь изменения на этом удалённом репозитории, сделайте какие-нибудь свои коммиты и затем скачайте \"чужие\" изменения. Это выглядит как несколько уроков в одном!"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -10,7 +10,8 @@ exports.level = {
|
|||
"pt_BR": "Histórico divergente",
|
||||
"de_DE": "Abweichende History",
|
||||
"fr_FR": "Historique divergent",
|
||||
"ja" : "履歴の分岐"
|
||||
"ja" : "履歴の分岐",
|
||||
"ru_RU": "Расхождение в истории"
|
||||
},
|
||||
"hint": {
|
||||
"en_US": "check out the ordering from the goal visualization",
|
||||
|
@ -20,7 +21,8 @@ exports.level = {
|
|||
"ot_BR": "Preste atenção na ordem da visualização do objetivo",
|
||||
"de_DE": "Beachte die Reihenfolge in der Zieldarstellung",
|
||||
"ja" : "ゴールのビジュアライズの順番を参照",
|
||||
"fr_FR": "regardez l'ordre dans la fenêtre de visualisation d'objectif"
|
||||
"fr_FR": "regardez l'ordre dans la fenêtre de visualisation d'objectif",
|
||||
"ru_RU": "проверьте сортировку в визуализации цели"
|
||||
},
|
||||
"startDialog": {
|
||||
"en_US": {
|
||||
|
@ -1023,6 +1025,149 @@ exports.level = {
|
|||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"ru_RU": {
|
||||
"childViews": [
|
||||
{
|
||||
"type": "ModalAlert",
|
||||
"options": {
|
||||
"markdowns": [
|
||||
"## Когда наработки расходятся",
|
||||
"",
|
||||
"Вот мы и познакомились с тем, как забирать (`pull`) чужие коммиты и как закачивать (`push`) свои наработки и изменения. Выглядит всё довольно просто, и не ясно какие же могу возникать у людей трудности со всем этим ?",
|
||||
"",
|
||||
"Сложности возникают тогда, когда история репозитория *расходится*. Давайте посмотрим на пример прежде чем идти дальше...",
|
||||
""
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ModalAlert",
|
||||
"options": {
|
||||
"markdowns": [
|
||||
"Представьте себе, Вы склонировали репозиторий в понедельник и начали разрабатывать какую-то новую и уникальную часть приложения (на сленге разработчиков - `фича`). В пятницу вечером Вы наконец-то готовы опубликовать Вашу фичу. Но, о нет! Ваш коллега в течении недели написал кучу кода, который делает все Ваши наработки устарелыми. Этот код был также закоммичен и опубликован на общедоступном удалённом репозитории, поэтому теперь *Ваш* код базируется на *устаревшей* версии проект и более не уместен.",
|
||||
"",
|
||||
"В этому случае использование комманды `git push` является сомнительным. Как поведёт себя комманда `git push` если Вы её выполните ? Может быть она изменит удалённый репозиторий и вернёт всё к тому состоянию, которое было в понедельник ? А может быть комманда попробует добавить Ваш код, не удаляя при этом новый? Или же она проигнорирует Ваши изменения, так как они уже устарели?",
|
||||
"",
|
||||
"По причине того, что в данной ситуации (когда история расходится) слишком много двусмысленностей и неопределённостей, git не даст Вам закачать (`push`) Ваши изменения. Чтобы поделится и закачать свои наработки, git будет принуждать Вас включить в состав своей работы все те последние наработки и изменения, находящиеся на удалённом репозитории."
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "GitDemonstrationView",
|
||||
"options": {
|
||||
"beforeMarkdowns": [
|
||||
"Слишком много болтавни! Давайте посмотрим, как всё работает на живом примере"
|
||||
],
|
||||
"afterMarkdowns": [
|
||||
"Видите? Ничего не произошло. Всё потому, что комманда `git push` не выполнилась успешно. Дело в том, что Ваш последний коммит `C3` основан на удалённом коммите `C1`. В свою очередь удалённый репозиторий уже изменился под воздействием `C2`. Вот почему git отклонил Ваш push."
|
||||
],
|
||||
"command": "git push",
|
||||
"beforeCommand": "git clone; git fakeTeamwork; git commit"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ModalAlert",
|
||||
"options": {
|
||||
"markdowns": [
|
||||
"Как же разрешит данную ситуацию? Всё очень просто! Всё что Вам нужно - перебазировать свою работу на наиболее последнюю версию удалённой ветки.",
|
||||
"",
|
||||
"Существует множество путей, как сделать это, но наиболее простой способ 'сдвинуть' свои наработки - через пребазировку или rebasing. Давайте посмотрим, как это выглядит."
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "GitDemonstrationView",
|
||||
"options": {
|
||||
"beforeMarkdowns": [
|
||||
"Теперь, когда мы сперва перебазиуемся прежде чем публиковать изменения..."
|
||||
],
|
||||
"afterMarkdowns": [
|
||||
"Опа! Мы только что обновили наш локальный образ удалённого репозитория средствами `git fetch`. Ещё мы перебазировали наши наработки, чтобы они отражали все изменения с удалённого репозитория, и опубликовали их с помощью `git push`"
|
||||
],
|
||||
"command": "git fetch; git rebase o/master; git push",
|
||||
"beforeCommand": "git clone; git fakeTeamwork; git commit"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ModalAlert",
|
||||
"options": {
|
||||
"markdowns": [
|
||||
"А есть ещё какие-либо варианты чтобы обновить мои наработки, к тому моменту как удалённый репозиторий был обновлён? Конечно есть! Давайте ознакомимся с парочкой новых штучек, но в этот раз с помощью комманды `merge`.",
|
||||
"",
|
||||
"Не смотря на то, что `git merge` не передвигает ваши наработки (а всего лишь создаёт новый коммит, в котором Ваши и удалённые изменения объеденены), этот способ помогает указать git-у на то, что Вы собираетесь включить в состав Ваших наработок все изменения с удалённого репозитория. Это значит, что Ваш коммит отразится на всех коммитах удалённой ветки, поскольку удалённая ветка является *предком* Вашей собственной локальной ветки.",
|
||||
"",
|
||||
"Давайте взглянем на демонстрацию..."
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "GitDemonstrationView",
|
||||
"options": {
|
||||
"beforeMarkdowns": [
|
||||
"Таким образм если мы объеденим (merge) вместо перебазирования (rebase)..."
|
||||
],
|
||||
"afterMarkdowns": [
|
||||
"Опа! Мы обновили наше локальное представление удалённого репозитория с помощью `git fetch`, *объединили* Ваши новые наработки с нашими наработками (чтобы отразить изменения в удалённом репозитории), и затем опубликовали их с помощью `git push`"
|
||||
],
|
||||
"command": "git fetch; git merge o/master; git push",
|
||||
"beforeCommand": "git clone; git fakeTeamwork; git commit"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ModalAlert",
|
||||
"options": {
|
||||
"markdowns": [
|
||||
"Здорово! А можно ли как-то зделать всё тоже самое, но с меньшим количеством комманд?",
|
||||
"",
|
||||
"Конечно -- ведь Вы уже знаете комманду `git pull`, которая является аналогом и более кратким аналогом для совместных fetch и merge. А команда `git pull --rebase` - аналог для совместно вызванных fetch и rebase!",
|
||||
"",
|
||||
"Давайте взглянем на эти оба варианта."
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "GitDemonstrationView",
|
||||
"options": {
|
||||
"beforeMarkdowns": [
|
||||
"Сперва - с флагом `--rebase`..."
|
||||
],
|
||||
"afterMarkdowns": [
|
||||
"Тот же результат как и ранее, но намного короче вызов команд."
|
||||
],
|
||||
"command": "git pull --rebase; git push",
|
||||
"beforeCommand": "git clone; git fakeTeamwork; git commit"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "GitDemonstrationView",
|
||||
"options": {
|
||||
"beforeMarkdowns": [
|
||||
"А теперь с обычным `pull`"
|
||||
],
|
||||
"afterMarkdowns": [
|
||||
"И снова - результат такой же, как и ранее!"
|
||||
],
|
||||
"command": "git pull; git push",
|
||||
"beforeCommand": "git clone; git fakeTeamwork; git commit"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ModalAlert",
|
||||
"options": {
|
||||
"markdowns": [
|
||||
"Рабочий процесс получения изменений (fetching), перебазирования/объединения (rebase/merging) и публикации изменений (pushing) довольно часто используемый. В последующий уроках мы изучим более сложные варианты этих рабочих процессов, но пока что, давайте остановимся на том, что есть.",
|
||||
"",
|
||||
"Выполните следующее, чтобы выполнить задание уровня:",
|
||||
"",
|
||||
"* Склонируйте репозиторий",
|
||||
"* Сфабрикуйте командную работу (1 коммит)",
|
||||
"* Сделайте свой собственный коммит (1 commit)",
|
||||
"* Опубликуйте свои наработки посредствам *перебазировки rebasing*"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -10,7 +10,8 @@ exports.level = {
|
|||
"pt_BR": "Git Pull",
|
||||
"de_DE": "Git Pull",
|
||||
"ja" : "Git Pull",
|
||||
"fr_FR": "Git pull"
|
||||
"fr_FR": "Git pull",
|
||||
"ru_RU": "Git pull"
|
||||
},
|
||||
"hint": {
|
||||
"en_US": "Just run git pull!",
|
||||
|
@ -20,7 +21,8 @@ exports.level = {
|
|||
"pt_BR": "Basta executar git pull!",
|
||||
"de_DE": "Führe einfach git pull aus.",
|
||||
"ja" : "単にgit pullを実行!",
|
||||
"fr_FR": "Utilisez facilement git pull !"
|
||||
"fr_FR": "Utilisez facilement git pull !",
|
||||
"ru_RU": "Запустите комманду git pull !"
|
||||
},
|
||||
"startDialog": {
|
||||
"en_US": {
|
||||
|
@ -435,6 +437,65 @@ exports.level = {
|
|||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"ru_RU": {
|
||||
"childViews": [
|
||||
{
|
||||
"type": "ModalAlert",
|
||||
"options": {
|
||||
"markdowns": [
|
||||
"## Git Pull",
|
||||
"",
|
||||
"Теперь, когда мы познакомились с тем, как извлекать данные из удалённого репозитория с помощью `git fetch`, давайте обновим нашу работу чтобы отобразить все эти изменения!",
|
||||
"",
|
||||
"Существует множество вариантов решений -- как только у вас имеется локальный коммит, Вы можете соединить его с другой веткой. Это значит Вы можете выполнить одну из комманд:",
|
||||
"",
|
||||
"* `git cherry-pick o/master`",
|
||||
"* `git rebase o/master`",
|
||||
"* `git merge o/master`",
|
||||
"* и т.д.",
|
||||
"",
|
||||
"По факту процедура *скачивания (fetching)* изменений с удалённой ветки и *объединения (merging)* настолько частая и распространённая, что git предоставляет вместо двух команд - одну! Эта команда - `git pull`."
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "GitDemonstrationView",
|
||||
"options": {
|
||||
"beforeMarkdowns": [
|
||||
"Давайте рассмотрим, как `fetch` и `merge` выполняются последовательно"
|
||||
],
|
||||
"afterMarkdowns": [
|
||||
"Опа -- мы скачали `C3` с помощью команды `fetch` и затем объединяем эти наработки с помощью `git merge o/master`. Теперь наша ветка `master` отображает изменения с удалённого репозитория (в данном случае с репозитория `origin`)"
|
||||
],
|
||||
"command": "git fetch; git merge o/master",
|
||||
"beforeCommand": "git clone; git commit; git fakeTeamwork"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "GitDemonstrationView",
|
||||
"options": {
|
||||
"beforeMarkdowns": [
|
||||
"Что же произойдёт если вместо этих команд мы воспользуемся `git pull` ?"
|
||||
],
|
||||
"afterMarkdowns": [
|
||||
"Абсолютно тоже самое! Нужно ясно и чётко понимать, что `git pull` существенно уменьшает Вашу рутинную работу, если бы Вы использовали `git fetch` и последующее слияние (merging) скаченной ветки."
|
||||
],
|
||||
"command": "git pull",
|
||||
"beforeCommand": "git clone; git commit; git fakeTeamwork"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ModalAlert",
|
||||
"options": {
|
||||
"markdowns": [
|
||||
"Мы изучим детали комманды `git pull` чуть позже (включая опции и аргументы вызова команды), а пока что давайте просто попробуем эту комманду.",
|
||||
"",
|
||||
"Помните -- мы также можете выполнить этот уровень с помощью комманд `fetch` и `merge`, но нужно ли делать так, когда можно воспользоваться всего-лишь одной коммандой ? :P"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -10,7 +10,8 @@ exports.level = {
|
|||
"pt_BR": "Git Push",
|
||||
"de_DE": "Git Push",
|
||||
"ja" : "Git Push",
|
||||
"fr_FR": "Git push"
|
||||
"fr_FR": "Git push",
|
||||
"ru_RU": "Git push"
|
||||
},
|
||||
"hint": {
|
||||
"en_US": "Remember you have to clone before you can push!",
|
||||
|
@ -20,7 +21,8 @@ exports.level = {
|
|||
"pt_BR": "Lembre-se de clonar antes de fazer o push!",
|
||||
"de_DE": "Denk dran, dass du einen Clone brauchst bevor du Pushen kannst!",
|
||||
"ja" : "Pushできる前にまずリポジトリをcloneする必要があるのをお忘れなく",
|
||||
"fr_FR": "Rappelez-vous que vous devez cloner avant de pouvoir faire un push !"
|
||||
"fr_FR": "Rappelez-vous que vous devez cloner avant de pouvoir faire un push !",
|
||||
"ru_RU": "Помните, что прежде чем push-ить вам нужно сколнировать репозиторий!"
|
||||
},
|
||||
"startDialog": {
|
||||
"en_US": {
|
||||
|
@ -315,6 +317,49 @@ exports.level = {
|
|||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"ru_RU": {
|
||||
"childViews": [
|
||||
{
|
||||
"type": "ModalAlert",
|
||||
"options": {
|
||||
"markdowns": [
|
||||
"## Git Push",
|
||||
"",
|
||||
"Хорошо, мы скачали изменения с удалённого репозитория и включили их в наши локальные наработки. Всё это замечательно, но, как нам поделиться _своими_ наработками и изменениями с другими участниками проекта?",
|
||||
"",
|
||||
"Способ, которым мы воспользуемся, является противоположным тому способу, которым мы пользовались ранее для скачивания наработок (`git pull`). Этот способ - использование комманды `git push`!",
|
||||
"",
|
||||
"Комманда `git push` отвечает за загрузку _Ваших_ изменений в указанный удалённый репозиторий, а также включение Ваших коммитов в состав удалённого репозитория. По окончанию работы комманды `git push` все Ваши друзья смогут скачать себе все сделанные Вами наработки.",
|
||||
"",
|
||||
"Вы можете рассматривать комманду `git push` как \"публикацию\" своей работы. Эта комманда скрывает в себе множество тонкостей и ньюансов, с которыми мы познакомимся в ближайшее время, а пока что давайте начнём с малого...",
|
||||
"",
|
||||
"*замечание -- поведение комманды `git push` без аргументов варьируется в зависимости он значения `push.default`,указанной в настройках git-а. Значение по-умолчанию зависит от версии git, которую Вы используете, однако в наших уроках мы будем использовать значение `upstream`. Лучше всегда проверят эту опцию прежде чем push-ить Ваши настоящие проекты.*"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "GitDemonstrationView",
|
||||
"options": {
|
||||
"beforeMarkdowns": [
|
||||
"Здесь у нас имеются изменения, которых нету в удалённом репозитории. Давайте же закачаем их туда!"
|
||||
],
|
||||
"afterMarkdowns": [
|
||||
"Вот так -- удалённый репозиторий получил новый коммит `C2`, ветка `master` на удалённом репозитории теперь указывает на `C2`, и наше *собственное* локальное отображение удалённого репозитория (`o/master`) изменилось соответственно. Всё синхронизировалось!"
|
||||
],
|
||||
"command": "git push",
|
||||
"beforeCommand": "git clone; git commit"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ModalAlert",
|
||||
"options": {
|
||||
"markdowns": [
|
||||
"Чтобы выполнить задачу этого упражнения, просто поделитесь своими двумя новыми коммитами с удалённым репозиторием. Соберитесь, потому что все последующие уроки будут намного сложнее предыдущих!"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -92,7 +92,10 @@ exports.level = {
|
|||
"type": "ModalAlert",
|
||||
"options": {
|
||||
"markdowns": [
|
||||
"Ok, for this level let's update both `foo` and `master` on the remote. The twist is that `git checkout` is disabled for this level!"
|
||||
"Ok, for this level let's update both `foo` and `master` on the remote. The twist is that `git checkout` is disabled for this level!",
|
||||
"",
|
||||
"*Note: The remote branches are labeled with `o/` prefixes because the full `origin/` label does not fit in our UI. Don't worry ",
|
||||
"about this... simply use `origin` as the name of the remote like normal.*"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,8 @@ exports.level = {
|
|||
"pt_BR": "Lembre-se que você sempre pode usar undo ou reset",
|
||||
"de_DE": "Denk dran, du kannst immer undo oder reset benutzen, um deine Befehle zurück zu nehmen.",
|
||||
"ja" : "undoやresetコマンドをいつでも使用することができるのをお忘れなく",
|
||||
"fr_FR": "Rappelez-vous que vous pouvez toujours utiliser les commandes undo et reset."
|
||||
"fr_FR": "Rappelez-vous que vous pouvez toujours utiliser les commandes undo et reset.",
|
||||
"ru_RU": "Помни - ты всегда можешь отменить комманды с помощью undo или reset"
|
||||
},
|
||||
"name": {
|
||||
"en_US": "Push Master!",
|
||||
|
@ -20,7 +21,8 @@ exports.level = {
|
|||
"pt_BR": "Push Master!",
|
||||
"de_DE": "Push Master!",
|
||||
"ja": "Push Master!",
|
||||
"fr_FR": "Maître du push !"
|
||||
"fr_FR": "Maître du push !",
|
||||
"ru_RU": "Push Мастер!"
|
||||
},
|
||||
"compareOnlyMasterHashAgnostic": true,
|
||||
"startDialog": {
|
||||
|
@ -394,6 +396,59 @@ exports.level = {
|
|||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"ru_RU": {
|
||||
"childViews": [
|
||||
{
|
||||
"type": "ModalAlert",
|
||||
"options": {
|
||||
"markdowns": [
|
||||
"## Слияние фича-бранчей (веток)",
|
||||
"",
|
||||
"Теперь, когда Вы умело владеете коммандами fetch, pull и push давайте применим эти навыки в сочетании с новым рабочим процессом (он же workflow).",
|
||||
"",
|
||||
"Для разработчиков, вовлечённых в большой проект, является довольно распространённым выполнять всё свою работу на так называемых фича-бранчах (вне `master`). А затем, как только работа выполнена, разработчик интегрирует всё что было им сделано. Всё это, за исключением одного шага, довольно похоже на предыдущий урок (там, где мы закачивали ветки на удалённый репозиторий)",
|
||||
"",
|
||||
"Ряд разработчиков делают push и pull лишь на локальную ветку `master` -- таким образом ветка `master` всегда обновлена с тем, что находится на удалённом репозитории (`o/master`).",
|
||||
"",
|
||||
"Для этого рабочего процесса мы совместили две вещи:",
|
||||
"",
|
||||
"* интеграция фича-бранчей в `master`, а также ",
|
||||
"* закачку (push) и скачку (pull) с удалённого репозитория"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "GitDemonstrationView",
|
||||
"options": {
|
||||
"beforeMarkdowns": [
|
||||
"Давайте быстренько вспомним, как нам обновить `master` и закачать выполненную работу."
|
||||
],
|
||||
"afterMarkdowns": [
|
||||
"Здесь мы выполнили две комманды, которые:",
|
||||
"",
|
||||
"* перебазировали нашу работу на новенький коммит, пришедший с удалённого репозитория, и",
|
||||
"* закачали свои наработки в удалённый репозиторий"
|
||||
],
|
||||
"command": "git pull --rebase; git push",
|
||||
"beforeCommand": "git clone; git commit; git fakeTeamwork"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ModalAlert",
|
||||
"options": {
|
||||
"markdowns": [
|
||||
"Текущая задача является достаточно обильной -- здесь представлена общая схема выполнения:",
|
||||
"",
|
||||
"* Есть три фича-бранчи (фича-ветки) -- `side1` `side2` и `side3`",
|
||||
"* Нам необходимо закачать каждую из них по очереди на удалённый репозиторий",
|
||||
"* При этом удалённый репозиторий хранит в себе какие-то наработки, которые также следует скачать к себе",
|
||||
"",
|
||||
":O Сложно! Желаю Вам удачи в выполнении этой непростой задачи."
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -865,6 +865,7 @@ div.displayName h3 {
|
|||
div.iconHolder {
|
||||
}
|
||||
|
||||
div.seriesView p.levelInfo,
|
||||
div.seriesView p.about {
|
||||
margin: 0px;
|
||||
padding: 4px;
|
||||
|
@ -872,6 +873,10 @@ div.seriesView p.about {
|
|||
color: #CCC;
|
||||
}
|
||||
|
||||
div.seriesView p.levelInfo {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div.levelIcon {
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
|
|
|
@ -222,6 +222,9 @@
|
|||
<p class="about">
|
||||
<%= about %>
|
||||
</p>
|
||||
<p class="levelInfo">
|
||||
<%= levelInfo %>
|
||||
</p>
|
||||
<div class="iconHolder box horizontal">
|
||||
<% for (var i = 0; i < ids.length; i++) { %>
|
||||
<div class="levelIcon box center centerAlign vertical" id="levelIcon-<%=ids[i]%>" data-id="<%=ids[i]%>">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue