changed in both
  base   100644 dfd9598f71c569e16f2a43e5ea61638af55c7417 app/src/lib/app-state.ts
  our    100644 b30f0fe080d909b81d2fb683ceb8deb365fb0191 app/src/lib/app-state.ts
  their  100644 ee5e509a6fae15273535d5e9f076be72dc7dea74 app/src/lib/app-state.ts
@@ -385,6 +385,9 @@
   /** Is a commit in progress? */
   readonly isCommitting: boolean
 
+  /** Is the index lockfile currently present in the repository? */
+  readonly isIndexLocked: boolean
+
   /** The date the repository was last fetched. */
   readonly lastFetched: Date | null
 
removed in local
  base   100644 c73d6ac64904f79320bb3aab8699dd2051c26f34 app/src/lib/dispatcher/app-store.ts
  their  100644 228a09b7eb27d2a0ed7ffe421a0641b94b3ffca4 app/src/lib/dispatcher/app-store.ts
added in remote
  their  100644 daacbb89a9229bdb2cc38953916cb8efcf223cf3 app/src/lib/dispatcher/index-watcher.ts
@@ -0,0 +1,92 @@
+import { Repository } from '../../models/repository'
+import { EventEmitter } from 'events'
+import * as Path from 'path'
+import * as Fs from 'fs'
+
+/**
+ * A component designed to monitor the repository filesystem for events
+ * involving the index.lock file. These events are raised using EventEmitter
+ * so the application can detect the presence of the lock file and prevent
+ * the user from committing at this time.
+ *
+ * This work leverages knowledge from reading the source of `file-watcher`
+ * (https://github.com/xpensia/file-watcher/) without requiring the full
+ * API surface.
+ */
+export class IndexWatcher extends EventEmitter {
+  private readonly gitDir: string
+
+  private watcher: Fs.FSWatcher | null
+
+  public constructor(repository: Repository) {
+    super()
+
+    this.gitDir = Path.join(repository.path, '.git')
+  }
+
+  public on(
+    event: 'index-changed',
+    listener: (isIndexLocked: boolean) => void
+  ): this {
+    return super.on(event, listener)
+  }
+
+  private onChanged = (isIndexLocked: boolean) => {
+    this.emit('index-changed', isIndexLocked)
+  }
+
+  private onChange = (event: string, filename: string) => {
+    const isValidPath = filename === 'index.lock'
+    if (!isValidPath) {
+      return
+    }
+
+    Fs.stat(Path.join(this.gitDir, filename), (err, stats) => {
+      if (err) {
+        if (err.code === 'ENOENT') {
+          this.onChanged(false)
+        } else {
+          log.warn('IndexWatcher encounted an unexpected error', err)
+        }
+        return
+      }
+
+      if (event === 'rename') {
+        this.onChanged(true)
+        return
+      }
+
+      log.warn(`IndexWatcher did not handle event '${event}'`)
+    })
+  }
+
+  /**
+   * Start monitoring the git directory for index.lock changes.
+   *
+   * Will error if the .git directory doesn't exist, or if the path provided
+   * isn't a valid repository.
+   */
+  public start() {
+    Fs.stat(this.gitDir, (err, stats) => {
+      if (err) {
+        throw err
+      }
+
+      if (!stats.isDirectory()) {
+        throw new Error('IndexWatcher not configured to watch a directory')
+      }
+
+      this.watcher = Fs.watch(this.gitDir, this.onChange)
+    })
+  }
+
+  /**
+   * Stop the watcher and cleanup any internal resources.
+   */
+  public stop() {
+    if (this.watcher) {
+      this.watcher.close()
+      this.watcher = null
+    }
+  }
+}
changed in both
  base   100644 0eb8418eb61309fccbf76303843a677fd8da9155 app/src/ui/changes/changes-list.tsx
  our    100644 f785abb2624c245a3387a304168d5fc629e1430e app/src/ui/changes/changes-list.tsx
  their  100644 f999c5420b7f1df504123231fc9b41266641fd2b app/src/ui/changes/changes-list.tsx
@@ -63,6 +63,7 @@
   readonly dispatcher: Dispatcher
   readonly availableWidth: number
   readonly isCommitting: boolean
+  readonly isIndexLocked: boolean
 
   /**
    * Click event handler passed directly to the onRowClick prop of List, see
@@ -405,8 +406,12 @@
           contextualCommitMessage={this.props.contextualCommitMessage}
           autocompletionProviders={this.props.autocompletionProviders}
           isCommitting={this.props.isCommitting}
+<<<<<<< .our
           showCoAuthoredBy={this.props.showCoAuthoredBy}
           coAuthors={this.props.coAuthors}
+=======
+          isIndexLocked={this.props.isIndexLocked}
+>>>>>>> .their
         />
       </div>
     )
changed in both
  base   100644 c620c6fd1f272a657ced3a46eb7f0dede18f1207 app/src/ui/changes/commit-message.tsx
  our    100644 0a0e18fc9f4c8956a648726827dc496f3d5f98db app/src/ui/changes/commit-message.tsx
  their  100644 07cbd6984c2fbdfc0dfc7a3d9daa486314f58420 app/src/ui/changes/commit-message.tsx
@@ -49,6 +49,7 @@
   readonly dispatcher: Dispatcher
   readonly autocompletionProviders: ReadonlyArray<IAutocompletionProvider<any>>
   readonly isCommitting: boolean
+<<<<<<< .our
 
   /**
    * Whether or not to show a field for adding co-authors to
@@ -64,6 +65,9 @@
    * the user has chosen to do so.
    */
   readonly coAuthors: ReadonlyArray<IAuthor>
+=======
+  readonly isIndexLocked: boolean
+>>>>>>> .their
 }
 
 interface ICommitMessageState {
@@ -470,7 +474,8 @@
 
   public render() {
     const branchName = this.props.branch ? this.props.branch : 'master'
-    const buttonEnabled = this.canCommit() && !this.props.isCommitting
+    const buttonEnabled =
+      this.canCommit() && !this.props.isCommitting && !this.props.isIndexLocked
 
     const loading = this.props.isCommitting ? <Loading /> : undefined
     const className = classNames({
changed in both
  base   100644 d950085a2ba2550df97783b087eab331cf671410 app/src/ui/changes/sidebar.tsx
  our    100644 ff1760bbd4b1a3d5ea8ac084b1282e99b2ea288b app/src/ui/changes/sidebar.tsx
  their  100644 12a7a87c27d9d551e2216ff5709dcf4fa6728d98 app/src/ui/changes/sidebar.tsx
@@ -46,6 +46,7 @@
   readonly isCommitting: boolean
   readonly isPushPullFetchInProgress: boolean
   readonly gitHubUserStore: GitHubUserStore
+  readonly isIndexLocked: boolean
   readonly askForConfirmationOnDiscardChanges: boolean
   readonly accounts: ReadonlyArray<Account>
   /** The name of the currently selected external editor */
@@ -310,10 +311,14 @@
           availableWidth={this.props.availableWidth}
           onIgnore={this.onIgnore}
           isCommitting={this.props.isCommitting}
+<<<<<<< .our
           showCoAuthoredBy={this.props.changes.showCoAuthoredBy}
           coAuthors={this.props.changes.coAuthors}
           externalEditorLabel={this.props.externalEditorLabel}
           onOpenInExternalEditor={this.props.onOpenInExternalEditor}
+=======
+          isIndexLocked={this.props.isIndexLocked}
+>>>>>>> .their
         />
         {this.renderMostRecentLocalCommit()}
       </div>
changed in both
  base   100644 5a428da019fc9c742d02e758a0503288463be322 app/src/ui/repository.tsx
  our    100644 efb00423012b8da0dfa5e8897acacaeb0a5e648a app/src/ui/repository.tsx
  their  100644 043bc5e7ba3cbc056ba3242f20b6dbcf547fd314 app/src/ui/repository.tsx
@@ -145,6 +145,7 @@
         availableWidth={availableWidth}
         gitHubUserStore={this.props.gitHubUserStore}
         isCommitting={this.props.state.isCommitting}
+        isIndexLocked={this.props.state.isIndexLocked}
         isPushPullFetchInProgress={this.props.state.isPushPullFetchInProgress}
         askForConfirmationOnDiscardChanges={
           this.props.askForConfirmationOnDiscardChanges
